Files
scripts/Perl OTRS/Kernel/Output/HTML/Layout/ITSMConfigItem.pm
2024-10-14 00:08:40 +02:00

738 lines
20 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::Output::HTML::Layout::ITSMConfigItem;
use strict;
use warnings;
our $ObjectManagerDisabled = 1;
=head1 NAME
Kernel::Output::HTML::Layout::ITSMConfigItem - all ConfigItem-related HTML functions
=head1 DESCRIPTION
All ITSM Configuration Management-related HTML functions
=head1 PUBLIC INTERFACE
=head2 ITSMConfigItemOutputStringCreate()
returns an output string
my $String = $LayoutObject->ITSMConfigItemOutputStringCreate(
Value => 11, # (optional)
Item => $ItemRef,
Print => 1, # (optional, default 0)
);
=cut
sub ITSMConfigItemOutputStringCreate {
my ( $Self, %Param ) = @_;
# check needed stuff
if ( !$Param{Item} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => 'Need Item!',
);
return;
}
# load backend
my $BackendObject = $Self->_ITSMLoadLayoutBackend(
Type => $Param{Item}->{Input}->{Type},
);
return '' if !$BackendObject;
# generate output string
my $String = $BackendObject->OutputStringCreate(%Param);
return $String;
}
=head2 ITSMConfigItemFormDataGet()
returns the values from the html form as hash reference
my $FormDataRef = $LayoutObject->ITSMConfigItemFormDataGet(
Key => 'Item::1::Node::3',
Item => $ItemRef,
ConfigItemID => 123,
);
=cut
sub ITSMConfigItemFormDataGet {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(Key Item ConfigItemID)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!"
);
return;
}
}
# load backend
my $BackendObject = $Self->_ITSMLoadLayoutBackend(
Type => $Param{Item}->{Input}->{Type},
);
return {} if !$BackendObject;
# get form data
my $FormData = $BackendObject->FormDataGet(%Param);
return $FormData;
}
=head2 ITSMConfigItemInputCreate()
returns a input field html string
my $String = $LayoutObject->ITSMConfigItemInputCreate(
Key => 'Item::1::Node::3',
Value => 11, # (optional)
Item => $ItemRef,
);
=cut
sub ITSMConfigItemInputCreate {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(Key Item)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!"
);
return;
}
}
# load backend
my $BackendObject = $Self->_ITSMLoadLayoutBackend(
Type => $Param{Item}->{Input}->{Type},
);
return '' if !$BackendObject;
# lookup item value
my $String = $BackendObject->InputCreate(%Param);
return $String;
}
=head2 ITSMConfigItemSearchFormDataGet()
returns the values from the search html form
my $ArrayRef = $LayoutObject->ITSMConfigItemSearchFormDataGet(
Key => 'Item::1::Node::3',
Item => $ItemRef,
);
=cut
sub ITSMConfigItemSearchFormDataGet {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(Key Item)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!"
);
return;
}
}
# load backend
my $BackendObject = $Self->_ITSMLoadLayoutBackend(
Type => $Param{Item}->{Input}->{Type},
);
return [] if !$BackendObject;
# get form data
my $Values = $BackendObject->SearchFormDataGet(%Param);
return $Values;
}
=head2 ITSMConfigItemSearchInputCreate()
returns a search input field html string
my $String = $LayoutObject->ITSMConfigItemSearchInputCreate(
Key => 'Item::1::Node::3',
Item => $ItemRef,
);
=cut
sub ITSMConfigItemSearchInputCreate {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(Key Item)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!"
);
return;
}
}
# load backend
my $BackendObject = $Self->_ITSMLoadLayoutBackend(
Type => $Param{Item}->{Input}->{Type},
);
return '' if !$BackendObject;
# lookup item value
my $String = $BackendObject->SearchInputCreate(%Param);
return $String;
}
=head2 _ITSMLoadLayoutBackend()
load a input type backend module
$BackendObject = $LayoutObject->_ITSMLoadLayoutBackend(
Type => 'GeneralCatalog',
);
=cut
sub _ITSMLoadLayoutBackend {
my ( $Self, %Param ) = @_;
# get log object
my $LogObject = $Kernel::OM->Get('Kernel::System::Log');
if ( !$Param{Type} ) {
$LogObject->Log(
Priority => 'error',
Message => 'Need Type!',
);
return;
}
my $GenericModule = "Kernel::Output::HTML::ITSMConfigItem::Layout$Param{Type}";
# load the backend module
if ( !$Kernel::OM->Get('Kernel::System::Main')->Require($GenericModule) ) {
$LogObject->Log(
Priority => 'error',
Message => "Can't load backend module $Param{Type}!"
);
return;
}
# create new instance
my $BackendObject = $GenericModule->new(
%{$Self},
%Param,
LayoutObject => $Self,
);
if ( !$BackendObject ) {
$LogObject->Log(
Priority => 'error',
Message => "Can't create a new instance of backend module $Param{Type}!",
);
return;
}
return $BackendObject;
}
=head2 ITSMConfigItemListShow()
Returns a list of configuration items with sort and pagination capabilities.
This function is similar to L<Kernel::Output::HTML::LayoutTicket::TicketListShow()>
in F<Kernel/Output/HTML/LayoutTicket.pm>.
my $Output = $LayoutObject->ITSMConfigItemListShow(
ConfigItemIDs => $ConfigItemIDsRef, # total list of config item ids, that can be listed
Total => scalar @{ $ConfigItemIDsRef }, # total number of list items, config items in this case
View => $Self->{View}, # optional, the default value is 'Small'
Filter => 'All',
Filters => \%NavBarFilter,
FilterLink => $LinkFilter,
TitleName => 'Overview: Config Item: Computer',
TitleValue => $Self->{Filter},
Env => $Self,
LinkPage => $LinkPage,
LinkSort => $LinkSort,
Frontend => 'Agent', # optional (Agent|Customer), default: Agent, indicates from which frontend this function was called
);
=cut
sub ITSMConfigItemListShow {
my ( $Self, %Param ) = @_;
# take object ref to local, remove it from %Param (prevent memory leak)
my $Env = delete $Param{Env};
# lookup latest used view mode
if ( !$Param{View} && $Self->{ 'UserITSMConfigItemOverview' . $Env->{Action} } ) {
$Param{View} = $Self->{ 'UserITSMConfigItemOverview' . $Env->{Action} };
}
# set frontend
my $Frontend = $Param{Frontend} || 'Agent';
# set defaut view mode to 'small'
my $View = $Param{View} || 'Small';
# store latest view mode
$Kernel::OM->Get('Kernel::System::AuthSession')->UpdateSessionID(
SessionID => $Self->{SessionID},
Key => 'UserITSMConfigItemOverview' . $Env->{Action},
Value => $View,
);
# get needed objects
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
# get backend from config
my $Backends = $ConfigObject->Get('ITSMConfigItem::Frontend::Overview');
if ( !$Backends ) {
return $LayoutObject->FatalError(
Message => 'Need config option ITSMConfigItem::Frontend::Overview',
);
}
# check for hash-ref
if ( ref $Backends ne 'HASH' ) {
return $LayoutObject->FatalError(
Message => 'Config option ITSMConfigItem::Frontend::Overview needs to be a HASH ref!',
);
}
# check for config key
if ( !$Backends->{$View} ) {
return $LayoutObject->FatalError(
Message => "No config option found for the view '$View'!",
);
}
# nav bar
my $StartHit = $Kernel::OM->Get('Kernel::System::Web::Request')->GetParam(
Param => 'StartHit',
) || 1;
# get personal page shown count
my $PageShownPreferencesKey = 'UserConfigItemOverview' . $View . 'PageShown';
my $PageShown = $Self->{$PageShownPreferencesKey} || 10;
my $Group = 'ConfigItemOverview' . $View . 'PageShown';
# check start option, if higher then elements available, set
# it to the last overview page (Thanks to Stefan Schmidt!)
if ( $StartHit > $Param{Total} ) {
my $Pages = int( ( $Param{Total} / $PageShown ) + 0.99999 );
$StartHit = ( ( $Pages - 1 ) * $PageShown ) + 1;
}
# get data selection
my %Data;
my $Config = $ConfigObject->Get('PreferencesGroups');
if ( $Config && $Config->{$Group} && $Config->{$Group}->{Data} ) {
%Data = %{ $Config->{$Group}->{Data} };
}
# set page limit and build page nav
my $Limit = $Param{Limit} || 20_000;
my %PageNav = $LayoutObject->PageNavBar(
Limit => $Limit,
StartHit => $StartHit,
PageShown => $PageShown,
AllHits => $Param{Total} || 0,
Action => 'Action=' . $Env->{Action},
Link => $Param{LinkPage},
);
# build shown ticket a page
$Param{RequestedURL} = $Param{RequestedURL} || "Action=$Self->{Action};$Param{LinkPage}";
$Param{Group} = $Group;
$Param{PreferencesKey} = $PageShownPreferencesKey;
$Param{PageShownString} = $Self->BuildSelection(
Name => $PageShownPreferencesKey,
SelectedID => $PageShown,
Data => \%Data,
Translation => 0,
Sort => 'NumericValue',
Class => 'Modernize',
);
# build navbar content
$LayoutObject->Block(
Name => 'OverviewNavBar',
Data => \%Param,
);
# back link
if ( $Param{LinkBack} ) {
$LayoutObject->Block(
Name => 'OverviewNavBarPageBack',
Data => \%Param,
);
$LayoutObject->AddJSData(
Key => 'ITSMConfigItemSearch',
Value => {
Profile => $Param{Profile},
ClassID => $Param{ClassID},
},
);
}
# get filters
if ( $Param{Filters} ) {
# get given filters
my @NavBarFilters;
for my $Prio ( sort keys %{ $Param{Filters} } ) {
push @NavBarFilters, $Param{Filters}->{$Prio};
}
# build filter content
$LayoutObject->Block(
Name => 'OverviewNavBarFilter',
Data => {
%Param,
},
);
# loop over filters
my $Count = 0;
for my $Filter (@NavBarFilters) {
# increment filter count and build filter item
$Count++;
$LayoutObject->Block(
Name => 'OverviewNavBarFilterItem',
Data => {
%Param,
%{$Filter},
},
);
# filter is selected
if ( $Filter->{Filter} eq $Param{Filter} ) {
$LayoutObject->Block(
Name => 'OverviewNavBarFilterItemSelected',
Data => {
%Param,
%{$Filter},
},
);
}
else {
$LayoutObject->Block(
Name => 'OverviewNavBarFilterItemSelectedNot',
Data => {
%Param,
%{$Filter},
},
);
}
}
}
# loop over configured backends
for my $Backend ( sort keys %{$Backends} ) {
# build navbar view mode
$LayoutObject->Block(
Name => 'OverviewNavBarViewMode',
Data => {
%Param,
%{ $Backends->{$Backend} },
Filter => $Param{Filter},
View => $Backend,
},
);
# current view is configured in backend
if ( $View eq $Backend ) {
$LayoutObject->Block(
Name => 'OverviewNavBarViewModeSelected',
Data => {
%Param,
%{ $Backends->{$Backend} },
Filter => $Param{Filter},
View => $Backend,
},
);
}
else {
$LayoutObject->Block(
Name => 'OverviewNavBarViewModeNotSelected',
Data => {
%Param,
%{ $Backends->{$Backend} },
Filter => $Param{Filter},
View => $Backend,
},
);
}
}
# check if page nav is available
if (%PageNav) {
$LayoutObject->Block(
Name => 'OverviewNavBarPageNavBar',
Data => \%PageNav,
);
# don't show context settings in AJAX case (e. g. in customer ticket history),
# because the submit with page reload will not work there
if ( !$Param{AJAX} ) {
$LayoutObject->Block(
Name => 'ContextSettings',
Data => {
%PageNav,
%Param,
},
);
}
}
# check if bulk feature is enabled
my $BulkFeature = 0;
if ( $ConfigObject->Get('ITSMConfigItem::Frontend::BulkFeature') ) {
my @Groups;
if ( $ConfigObject->Get('ITSMConfigItem::Frontend::BulkFeatureGroup') ) {
@Groups = @{ $ConfigObject->Get('ITSMConfigItem::Frontend::BulkFeatureGroup') };
}
if ( !@Groups ) {
$BulkFeature = 1;
}
else {
GROUP:
for my $Group (@Groups) {
next GROUP if !$Kernel::OM->Get('Kernel::System::Group')->PermissionCheck(
UserID => $Self->{UserID},
GroupName => $Group,
Type => 'rw',
);
$BulkFeature = 1;
last GROUP;
}
}
}
# show the bulk action button if feature is enabled
if ($BulkFeature) {
$LayoutObject->Block(
Name => 'BulkAction',
Data => {
%PageNav,
%Param,
},
);
}
# build html content
my $OutputNavBar = $LayoutObject->Output(
TemplateFile => 'AgentITSMConfigItemOverviewNavBar',
Data => {%Param},
);
# create output
my $OutputRaw = '';
if ( !$Param{Output} ) {
$LayoutObject->Print(
Output => \$OutputNavBar,
);
}
else {
$OutputRaw .= $OutputNavBar;
}
# load module
if ( !$Kernel::OM->Get('Kernel::System::Main')->Require( $Backends->{$View}->{Module} ) ) {
return $LayoutObject->FatalError();
}
# check for backend object
my $Object = $Backends->{$View}->{Module}->new( %{$Env} );
return if !$Object;
# run module
my $Output = $Object->Run(
%Param,
Limit => $Limit,
StartHit => $StartHit,
PageShown => $PageShown,
AllHits => $Param{Total} || 0,
Frontend => $Frontend,
);
# create output
if ( !$Param{Output} ) {
$LayoutObject->Print(
Output => \$Output,
);
}
else {
$OutputRaw .= $Output;
}
# create overview nav bar
$LayoutObject->Block(
Name => 'OverviewNavBar',
Data => {%Param},
);
# return content if available
return $OutputRaw;
}
=head2 XMLData2Hash()
returns a hash reference with the requested attributes data for a config item
Return
$Data = {
'HardDisk::2' => {
Value => 'HD2',
Name => 'Hard Disk',
},
'CPU::1' => {
Value => '',
Name => 'CPU',
},
'HardDisk::2::Capacity::1' => {
Value => '780 GB',
Name => 'Capacity',
},
};
my $Data = $LayoutObject->XMLData2Hash(
XMLDefinition => $Version->{XMLDefinition},
XMLData => $Version->{XMLData}->[1]->{Version}->[1],
Attributes => ['CPU::1', 'HardDrive::2::Capacity::1', ...],
Data => \%DataHashRef, # optional
Prefix => 'HardDisk::1', # optional
);
=cut
sub XMLData2Hash {
my ( $Self, %Param ) = @_;
# check needed stuff
return if !$Param{XMLData};
return if !$Param{XMLDefinition};
return if !$Param{Attributes};
return if ref $Param{XMLData} ne 'HASH';
return if ref $Param{XMLDefinition} ne 'ARRAY';
return if ref $Param{Attributes} ne 'ARRAY';
# to store the return data
my $Data = $Param{Data} || {};
# create a lookup structure
my %RelevantAttributes = map { $_ => 1 } @{ $Param{Attributes} };
ITEM:
for my $Item ( @{ $Param{XMLDefinition} } ) {
my $CountMax = $Item->{CountMax} || 1;
COUNTER:
for my $Counter ( 1 .. $CountMax ) {
# add prefix
my $Prefix = $Item->{Key} . '::' . $Counter;
if ( $Param{Prefix} ) {
$Prefix = $Param{Prefix} . '::' . $Prefix;
}
# skip not needed elements and sub elements
next COUNTER if !grep { $_ =~ m{\A$Prefix} } @{ $Param{Attributes} };
# lookup value
my $Value = $Kernel::OM->Get('Kernel::System::ITSMConfigItem')->XMLValueLookup(
Item => $Item,
Value => $Param{XMLData}->{ $Item->{Key} }->[$Counter]->{Content} // '',
);
# only if value is defined
if ( defined $Value ) {
# create output string
$Value = $Self->ITSMConfigItemOutputStringCreate(
Value => $Value,
Item => $Item,
Print => $Param{Print},
);
}
if ( $RelevantAttributes{$Prefix} ) {
# store the item in hash
$Data->{$Prefix} = {
Name => $Item->{Name},
Value => $Value // '',
};
}
# start recursion, if "Sub" was found
if ( $Item->{Sub} ) {
$Data = $Self->XMLData2Hash(
XMLDefinition => $Item->{Sub},
XMLData => $Param{XMLData}->{ $Item->{Key} }->[$Counter],
Prefix => $Prefix,
Data => $Data,
Attributes => $Param{Attributes},
);
}
}
}
return $Data;
}
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