2923 lines
145 KiB
Perl
2923 lines
145 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::System::SysConfig::Migration;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use parent qw(scripts::DBUpdateTo6::Base);
|
|
|
|
use List::Util qw(first);
|
|
|
|
our @ObjectDependencies = (
|
|
'Kernel::System::Log',
|
|
'Kernel::System::Main',
|
|
'Kernel::System::SysConfig',
|
|
);
|
|
|
|
use Kernel::System::VariableCheck qw( :all );
|
|
|
|
=head1 NAME
|
|
|
|
Kernel::System::SysConfig::Migration - System configuration settings migration tools.
|
|
|
|
=head1 PUBLIC INTERFACE
|
|
|
|
=head2 new()
|
|
|
|
Create an object. Do not use it directly, instead use:
|
|
|
|
use Kernel::System::ObjectManager;
|
|
local $Kernel::OM = Kernel::System::ObjectManager->new();
|
|
my $SysConfigMigrationObject = $Kernel::OM->Get('Kernel::System::SysConfig::Migration');
|
|
|
|
=cut
|
|
|
|
sub new {
|
|
my ( $Type, %Param ) = @_;
|
|
|
|
# allocate new hash for object
|
|
my $Self = {};
|
|
bless( $Self, $Type );
|
|
|
|
return $Self;
|
|
}
|
|
|
|
=head2 MigrateXMLStructure()
|
|
|
|
Migrate XML file content from OTRS 5 to OTRS 6.
|
|
|
|
my $Result = $SysConfigMigrationObject->MigrateXMLStructure(
|
|
Content => '
|
|
<?xml version="1.0" encoding="utf-8" ?>
|
|
<otrs_config version="1.0" init="Framework">
|
|
...
|
|
</otrs_config>',
|
|
Name => 'Framework',
|
|
);
|
|
|
|
Returns:
|
|
|
|
$Result = '
|
|
<?xml version="1.0" encoding="utf-8" ?>
|
|
<otrs_config version="2.0" init="Framework">
|
|
...
|
|
</otrs_config>';
|
|
|
|
=cut
|
|
|
|
sub MigrateXMLStructure {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
for my $Needed (qw(Content Name)) {
|
|
if ( !$Param{$Needed} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $Needed!",
|
|
);
|
|
return;
|
|
}
|
|
}
|
|
|
|
my $Init = "";
|
|
if ( $Param{Content} =~ m{<otrs_config.*?init="(.*?)"} ) {
|
|
$Init = $1;
|
|
}
|
|
|
|
# Stop if we don't have Init (configuration xml file is corrupt or invalid).
|
|
return if !$Init;
|
|
|
|
# Stop if its a configuration file is not from OTRS 5 or prior (OTRS 6 uses version 2.0).
|
|
return if !$Param{Content} =~ m{^<otrs_config.*?version="1.0"}gsmx;
|
|
|
|
# Split settings - prevent deleting some settings due to greedy RegEx. Each array item contains
|
|
# only one setting.
|
|
my @Settings = split( "</ConfigItem>", $Param{Content} );
|
|
|
|
my %InitToLoaderMapping = (
|
|
Framework => '001-',
|
|
Application => '002-',
|
|
Config => '003-',
|
|
Changes => '004-',
|
|
);
|
|
|
|
my %NavigationLookup = $Self->NavigationLookupGet();
|
|
|
|
my @Frontends;
|
|
|
|
SETTING:
|
|
for my $Setting (@Settings) {
|
|
|
|
# Stop the setting loop process if it's the ending tag.
|
|
last SETTING if $Setting =~ m/<\/otrs_config>/i;
|
|
|
|
# Update version (from 1.0 to 2.0).
|
|
$Setting =~ s{^(<otrs_config.*?version)="1.0"}{$1="2.0"}gsmx;
|
|
$Setting .= "</ConfigItem>";
|
|
|
|
# Update to preferences group
|
|
if ( $Setting =~ m{PreferencesGroups###} && $Setting =~ m{<Item Key="Column">} ) {
|
|
$Setting =~ s{<Item\s+Key="Column">}{<Item Key="PreferenceGroup">}gsmx;
|
|
}
|
|
|
|
# Check if FrontendModuleReg.
|
|
if ( $Setting =~ m{<FrontendModuleReg>} ) {
|
|
|
|
# Extract Loader and delete.
|
|
my $Loader;
|
|
if ( $Setting =~ s{\s+<Loader>(.*?)</Loader>$}{}gsmx ) {
|
|
$Loader = $1;
|
|
}
|
|
|
|
# Extract NavBar and delete
|
|
my $NavBar;
|
|
|
|
if ( $Setting =~ s{\s+<NavBar>(.*)</NavBar>$}{}gsmx ) {
|
|
$NavBar = "<NavBar>\n$1</NavBar>\n";
|
|
}
|
|
|
|
# Extract NavBarModule and delete
|
|
my $NavBarModule;
|
|
if ( $Setting =~ s{\s+<NavBarModule>(.*?)</NavBarModule>$}{}gsmx ) {
|
|
$NavBarModule = $1;
|
|
}
|
|
|
|
# Extract FrontendModuleReg and delete.
|
|
$Setting =~ s{<FrontendModuleReg>(.*?)</FrontendModuleReg>}{}gsmx;
|
|
my $FrontendModuleReg = $1;
|
|
|
|
# Split on new line.
|
|
my @Lines = split( "\n", $FrontendModuleReg );
|
|
|
|
LINE:
|
|
for my $Line (@Lines) {
|
|
|
|
my $Tag;
|
|
|
|
# Extract tag name.
|
|
if ( $Line =~ m{</(.*?)>} ) {
|
|
$Tag = $1;
|
|
}
|
|
|
|
next LINE if !$Tag;
|
|
|
|
# Create Item to replace $Tag.
|
|
$Line =~ s{<$Tag(.*?)</$Tag>}{<Item Key="$Tag"$1</Item>}gsmx;
|
|
}
|
|
|
|
$FrontendModuleReg = join( "\n", @Lines );
|
|
|
|
my %GroupItems;
|
|
|
|
@Lines = split( "\n", $FrontendModuleReg );
|
|
my @OutputLines;
|
|
|
|
LINE:
|
|
for my $Line (@Lines) {
|
|
next LINE if !$Line;
|
|
|
|
$Line =~ m{Item Key="(.*?)"};
|
|
my $ItemKey = $1 || '';
|
|
|
|
if ( $ItemKey eq 'Group' || $ItemKey eq 'GroupRo' ) {
|
|
$Line =~ m{<Item.*?>(.*?)</Item>}gsmg;
|
|
my $Value = $1;
|
|
|
|
if ( $GroupItems{$ItemKey} ) {
|
|
push @{ $GroupItems{$ItemKey} }, $Value;
|
|
|
|
# Skip this line.
|
|
next LINE;
|
|
}
|
|
else {
|
|
$GroupItems{$ItemKey} = [$Value];
|
|
|
|
# Put Placeholder.
|
|
$Line =~ s{^(\s+)<Item.*?</Item>.*?$}{$1 PLACEHOLDER_$ItemKey _END}gsmx;
|
|
}
|
|
}
|
|
|
|
$Line = " $Line";
|
|
push @OutputLines, $Line;
|
|
}
|
|
|
|
$FrontendModuleReg = join( "\n", @OutputLines );
|
|
my $FirstItem = 1;
|
|
|
|
for my $Key ( sort keys %GroupItems ) {
|
|
|
|
if ( ref $GroupItems{$Key} eq 'ARRAY' ) {
|
|
my $ArrayItems = '';
|
|
if ($FirstItem) {
|
|
$ArrayItems .= "\n";
|
|
}
|
|
|
|
$ArrayItems .= sprintf "%-*s%s", 20, "",
|
|
"<Item Key=\"$Key\">\n";
|
|
$ArrayItems .= sprintf "%-*s%s", 24, "",
|
|
"<Array>\n";
|
|
|
|
for my $ArrayItem ( @{ $GroupItems{$Key} } ) {
|
|
if ($ArrayItem) {
|
|
$ArrayItems .= sprintf "%-*s%s", 28, "",
|
|
"<Item>$ArrayItem</Item>\n";
|
|
}
|
|
}
|
|
$ArrayItems .= sprintf "%-*s%s", 24, "",
|
|
"</Array>\n";
|
|
$ArrayItems .= sprintf "%-*s%s", 20, "",
|
|
"</Item>";
|
|
|
|
$FrontendModuleReg =~ s{^\s+PLACEHOLDER_$Key\s_END.*?$}{$ArrayItems}gsmx;
|
|
}
|
|
$FirstItem = 0;
|
|
}
|
|
|
|
# Make sure each FrontendModuleReg has Group and GroupRo items
|
|
for my $GroupTag (qw(GroupRo Group)) {
|
|
if ( $FrontendModuleReg !~ m{<Item Key="$GroupTag"} ) {
|
|
|
|
my $MissingTag = sprintf "%-*s%s", 20, "",
|
|
"<Item Key=\"$GroupTag\">\n";
|
|
|
|
$MissingTag .= sprintf "%-*s%s", 24, "",
|
|
"<Array>\n";
|
|
$MissingTag .= sprintf "%-*s%s", 24, "",
|
|
"</Array>\n";
|
|
$MissingTag .= sprintf "%-*s%s", 20, "",
|
|
"</Item>\n";
|
|
|
|
# prepend
|
|
$FrontendModuleReg = $MissingTag .= $FrontendModuleReg;
|
|
}
|
|
}
|
|
|
|
# check if NavBarName exists
|
|
if ( $FrontendModuleReg !~ m{<Item Key="NavBarName"} ) {
|
|
$FrontendModuleReg .= sprintf "%-*s%s", 4, "",
|
|
"<Item Key=\"NavBarName\"></Item>\n";
|
|
$FrontendModuleReg .= sprintf "%-*s", 16, "";
|
|
}
|
|
|
|
my $FirstCharacter = substr $FrontendModuleReg, 0, 1;
|
|
if ( $FirstCharacter ne "\n" ) {
|
|
$FrontendModuleReg = "\n$FrontendModuleReg";
|
|
}
|
|
|
|
my $Value = "<Value>\n";
|
|
$Value .= sprintf "%-*s%s", 12, "", "<Item ValueType=\"FrontendRegistration\">\n";
|
|
$Value .= sprintf "%-*s%s", 16, "", "<Hash>";
|
|
$Value .= $FrontendModuleReg;
|
|
$Value .= "</Hash>\n";
|
|
$Value .= sprintf "%-*s%s", 12, "", "</Item>\n";
|
|
$Value .= sprintf "%-*s%s", 8, "", "</Value>";
|
|
|
|
$Setting =~ s{<Setting>.*?</Setting>}{$Value}gsmx;
|
|
|
|
# Put Loader stuff in a separated setting.
|
|
if (
|
|
$Loader
|
|
&& $Setting =~ m{<ConfigItem\s+Name="(.*?)"(.*?)>}gsmx
|
|
)
|
|
{
|
|
my $LoaderSetting = sprintf "%-*s%s", 4, "", "<ConfigItem Name=\"$1\"$2>";
|
|
|
|
my $LoaderName = ( $InitToLoaderMapping{$Init} // '005-' )
|
|
. $Param{Name};
|
|
|
|
$LoaderSetting =~ s{Name=".*?\#\#\#(.*?)" (.*?)>}{Name="Loader::Module::$1###$LoaderName"$2>}gsmx;
|
|
|
|
$LoaderSetting .= sprintf(
|
|
"\n%-*s%s",
|
|
8,
|
|
"",
|
|
"<Description Translatable=\"1\">Loader module registration for the agent interface.</Description>"
|
|
);
|
|
|
|
if ( $Setting =~ m{<SubGroup>(.*?)</SubGroup>} ) {
|
|
my $NavigationStr = $NavigationLookup{$1} || $1;
|
|
|
|
$NavigationStr .= "::Loader";
|
|
$LoaderSetting .= sprintf( "\n%-*s%s", 8, "", "<Navigation>$NavigationStr</Navigation>" );
|
|
}
|
|
|
|
$LoaderSetting .= sprintf( "\n%-*s%s", 8, "", "<Value>" );
|
|
$LoaderSetting .= sprintf( "\n%-*s%s", 12, "", "<Hash>" );
|
|
|
|
my @LoaderLines = split( "\n", $Loader );
|
|
my ( @CSS, @JS );
|
|
|
|
# Check for CSS and JS content.
|
|
for my $Line (@LoaderLines) {
|
|
if ( $Line =~ m{<CSS>(.*?)</CSS>} ) {
|
|
push @CSS, $1;
|
|
}
|
|
|
|
if ( $Line =~ m{<JavaScript>(.*?)</JavaScript>} ) {
|
|
push @JS, $1;
|
|
}
|
|
}
|
|
|
|
if ( scalar @CSS ) {
|
|
$LoaderSetting .= sprintf( "\n%-*s%s", 16, "", "<Item Key=\"CSS\">" );
|
|
$LoaderSetting .= sprintf( "\n%-*s%s", 20, "", "<Array>" );
|
|
}
|
|
|
|
for my $CSSItem (@CSS) {
|
|
$LoaderSetting .= sprintf( "\n%-*s%s", 24, "", "<Item>$CSSItem</Item>" );
|
|
}
|
|
|
|
if ( scalar @CSS ) {
|
|
$LoaderSetting .= sprintf( "\n%-*s%s", 20, "", "</Array>" );
|
|
$LoaderSetting .= sprintf( "\n%-*s%s", 16, "", "</Item>" );
|
|
}
|
|
|
|
if ( scalar @JS ) {
|
|
$LoaderSetting .= sprintf( "\n%-*s%s", 16, "", "<Item Key=\"JavaScript\">" );
|
|
$LoaderSetting .= sprintf( "\n%-*s%s", 20, "", "<Array>" );
|
|
}
|
|
|
|
for my $JSItem (@JS) {
|
|
$LoaderSetting .= sprintf( "\n%-*s%s", 24, "", "<Item>$JSItem</Item>" );
|
|
}
|
|
|
|
if ( scalar @JS ) {
|
|
$LoaderSetting .= sprintf( "\n%-*s%s", 20, "", "</Array>" );
|
|
$LoaderSetting .= sprintf( "\n%-*s%s", 16, "", "</Item>" );
|
|
}
|
|
|
|
$LoaderSetting .= sprintf( "\n%-*s%s", 12, "", "</Hash>" );
|
|
$LoaderSetting .= sprintf( "\n%-*s%s", 8, "", "</Value>" );
|
|
$LoaderSetting .= sprintf( "\n%-*s%s", 4, "", "</ConfigItem>" );
|
|
|
|
$Setting .= "\n" . $LoaderSetting;
|
|
}
|
|
|
|
if ( $NavBar && $Setting =~ m{<ConfigItem\s+Name="(.*?)"(.*?)>}gsmx ) {
|
|
my $Name = $1;
|
|
my $Options = $2;
|
|
|
|
my @NavBars = split m{<\/NavBar>\s+?<NavBar}, $NavBar;
|
|
|
|
$Name =~ s{Frontend::Module}{Frontend::Navigation}gsmx;
|
|
$Name .= '###' . ( $InitToLoaderMapping{$Init} // '005-' ) . $Param{Name};
|
|
|
|
my $Navigation = sprintf "%-*s%s", 4, "", "<Setting Name=\"$Name\"$Options>\n";
|
|
$Navigation .= sprintf "%-*s%s", 8, "",
|
|
"<Description Translatable=\"1\">Main menu item registration.</Description>";
|
|
|
|
if ( $Setting =~ m{<SubGroup>(.*?)</SubGroup>} ) {
|
|
my $NavigationStr = $NavigationLookup{$1} || $1;
|
|
$NavigationStr .= "::MainMenu";
|
|
$Navigation .= sprintf( "\n%-*s%s", 8, "", "<Navigation>$NavigationStr</Navigation>" );
|
|
}
|
|
|
|
$Navigation .= sprintf( "\n%-*s%s", 8, "", "<Value>" );
|
|
$Navigation .= sprintf( "\n%-*s%s", 12, "", "<Array>" );
|
|
$Navigation .= sprintf( "\n%-*s%s", 16, "", "<DefaultItem ValueType=\"FrontendNavigation\">" );
|
|
$Navigation .= sprintf( "\n%-*s%s", 20, "", "<Hash>" );
|
|
$Navigation .= sprintf( "\n%-*s%s", 20, "", "</Hash>" );
|
|
$Navigation .= sprintf( "\n%-*s%s", 16, "", "</DefaultItem>" );
|
|
|
|
for my $NavBarItem (@NavBars) {
|
|
|
|
$Navigation .= sprintf( "\n%-*s%s", 16, "", "<Item>" );
|
|
$Navigation .= sprintf( "\n%-*s%s", 20, "", "<Hash>" );
|
|
|
|
for my $NavBarTag (qw(Group GroupRo)) {
|
|
my @Items;
|
|
|
|
while ( $NavBarItem =~ s{<$NavBarTag>(.*?)<\/$NavBarTag}{}smx ) {
|
|
push @Items, $1;
|
|
}
|
|
|
|
$Navigation .= sprintf( "\n%-*s%s", 24, "", "<Item Key=\"$NavBarTag\">" );
|
|
$Navigation .= sprintf( "\n%-*s%s", 28, "", "<Array>" );
|
|
|
|
for my $Value (@Items) {
|
|
$Navigation .= sprintf( "\n%-*s%s", 32, "", "<Item>$Value</Item>" );
|
|
}
|
|
|
|
if (
|
|
!scalar @Items
|
|
&& $GroupItems{$NavBarTag}
|
|
)
|
|
{
|
|
# take group items from FrontendModuleReg
|
|
for my $Value ( @{ $GroupItems{$NavBarTag} } ) {
|
|
if ($Value) {
|
|
$Navigation .= sprintf( "\n%-*s%s", 32, "", "<Item>$Value</Item>" );
|
|
}
|
|
}
|
|
}
|
|
|
|
$Navigation .= sprintf( "\n%-*s%s", 28, "", "</Array>" );
|
|
$Navigation .= sprintf( "\n%-*s%s", 24, "", "</Item>" );
|
|
}
|
|
|
|
for my $NavBarTag (qw(Description Name Link LinkOption NavBar Type Block AccessKey Prio)) {
|
|
my $Value = '';
|
|
my $Attributes = '';
|
|
|
|
if ( $NavBarItem =~ m{<$NavBarTag>(.*?)<\/$NavBarTag} ) {
|
|
$Value = $1;
|
|
}
|
|
elsif ( $NavBarItem =~ m{<$NavBarTag\s(.*?)>(.*?)<\/$NavBarTag} ) {
|
|
$Attributes = " $1";
|
|
$Value = $2;
|
|
}
|
|
$Navigation .= sprintf(
|
|
"\n%-*s%s", 24, "",
|
|
"<Item Key=\"$NavBarTag\"$Attributes>$Value</Item>",
|
|
);
|
|
}
|
|
|
|
$Navigation .= sprintf( "\n%-*s%s", 20, "", "</Hash>" );
|
|
$Navigation .= sprintf( "\n%-*s%s", 16, "", "</Item>" );
|
|
}
|
|
|
|
$Navigation .= sprintf( "\n%-*s%s", 12, "", "</Array>" );
|
|
$Navigation .= sprintf( "\n%-*s%s", 8, "", "</Value>" );
|
|
$Navigation .= sprintf( "\n%-*s%s", 4, "", "</ConfigItem>\n" ); # We rename ConfigItems later
|
|
|
|
$Setting .= "\n" . $Navigation;
|
|
}
|
|
elsif ( !$NavBar && $Setting =~ m{<ConfigItem\s+Name="(.*?)"(.*?)>}gsmx ) {
|
|
my $Name = $1;
|
|
my $Options = $2;
|
|
|
|
my %NoDefaultNavigationSetting = (
|
|
'CustomerFrontend::Module###AjaxAttachment' => 1,
|
|
'CustomerFrontend::Module###CustomerAccept' => 1,
|
|
'CustomerFrontend::Module###CustomerChatDownload' => 1,
|
|
'CustomerFrontend::Module###CustomerDynamicFieldDatabaseDetailedSearch' => 1,
|
|
'CustomerFrontend::Module###CustomerDynamicFieldDatabaseDetails' => 1,
|
|
'CustomerFrontend::Module###CustomerDynamicFieldDatabaseSearch' => 1,
|
|
'CustomerFrontend::Module###CustomerTicketArticleContent' => 1,
|
|
'CustomerFrontend::Module###CustomerTicketAttachment' => 1,
|
|
'CustomerFrontend::Module###CustomerTicketPrint' => 1,
|
|
'CustomerFrontend::Module###CustomerTicketZoom' => 1,
|
|
'CustomerFrontend::Module###CustomerVideoChat' => 1,
|
|
'CustomerFrontend::Module###Login' => 1,
|
|
'CustomerFrontend::Module###Logout' => 1,
|
|
'CustomerFrontend::Module###PictureUpload' => 1,
|
|
'Frontend::Module###AdminAppointmentImport' => 1,
|
|
'Frontend::Module###AdminDynamicFieldCheckbox' => 1,
|
|
'Frontend::Module###AdminDynamicFieldContactWithData' => 1,
|
|
'Frontend::Module###AdminDynamicFieldDatabase' => 1,
|
|
'Frontend::Module###AdminDynamicFieldDateTime' => 1,
|
|
'Frontend::Module###AdminDynamicFieldDropdown' => 1,
|
|
'Frontend::Module###AdminDynamicFieldMultiselect' => 1,
|
|
'Frontend::Module###AdminDynamicFieldText' => 1,
|
|
'Frontend::Module###AdminDynamicFieldWebService' => 1,
|
|
'Frontend::Module###AdminGenericInterfaceErrorHandlingDefault' => 1,
|
|
'Frontend::Module###AdminGenericInterfaceErrorHandlingRequestRetry' => 1,
|
|
'Frontend::Module###AdminGenericInterfaceInvokerDefault' => 1,
|
|
'Frontend::Module###AdminGenericInterfaceInvokerEvent' => 1,
|
|
'Frontend::Module###AdminGenericInterfaceMappingSimple' => 1,
|
|
'Frontend::Module###AdminGenericInterfaceMappingXSLT' => 1,
|
|
'Frontend::Module###AdminGenericInterfaceOperationDefault' => 1,
|
|
'Frontend::Module###AdminGenericInterfaceTransportHTTPREST' => 1,
|
|
'Frontend::Module###AdminGenericInterfaceTransportHTTPSOAP' => 1,
|
|
'Frontend::Module###AdminGenericInterfaceWebserviceHistory' => 1,
|
|
'Frontend::Module###AdminInit' => 1,
|
|
'Frontend::Module###AdminProcessManagementActivity' => 1,
|
|
'Frontend::Module###AdminProcessManagementActivityDialog' => 1,
|
|
'Frontend::Module###AdminProcessManagementPath' => 1,
|
|
'Frontend::Module###AdminProcessManagementTransition' => 1,
|
|
'Frontend::Module###AdminProcessManagementTransitionAction' => 1,
|
|
'Frontend::Module###AgentAppointmentEdit' => 1,
|
|
'Frontend::Module###AgentAppointmentPluginSearch' => 1,
|
|
'Frontend::Module###AgentChatAppend' => 1,
|
|
'Frontend::Module###AgentChatAvailability' => 1,
|
|
'Frontend::Module###AgentChatDownload' => 1,
|
|
'Frontend::Module###AgentChatPopup' => 1,
|
|
'Frontend::Module###AgentChatPreview' => 1,
|
|
'Frontend::Module###AgentContactWithDataSearch' => 1,
|
|
'Frontend::Module###AgentCustomerSearch' => 1,
|
|
'Frontend::Module###AgentCustomerSearchSMS' => 1,
|
|
'Frontend::Module###AgentCustomerUserAddressBook' => 1,
|
|
'Frontend::Module###AgentCustomerUserInformationCenterSearch' => 1,
|
|
'Frontend::Module###AgentDaemonInfo' => 1,
|
|
'Frontend::Module###AgentDynamicFieldDatabaseDetailedSearch' => 1,
|
|
'Frontend::Module###AgentDynamicFieldDatabaseDetails' => 1,
|
|
'Frontend::Module###AgentDynamicFieldDatabaseSearch' => 1,
|
|
'Frontend::Module###AgentInfo' => 1,
|
|
'Frontend::Module###AgentHTMLReference' => 1,
|
|
'Frontend::Module###AgentOTRSBusiness' => 1,
|
|
'Frontend::Module###AgentSplitSelection' => 1,
|
|
'Frontend::Module###AgentTicketArticleContent' => 1,
|
|
'Frontend::Module###AgentTicketAttachment' => 1,
|
|
'Frontend::Module###AgentTicketAttachmentView' => 1,
|
|
'Frontend::Module###AgentTicketBounce' => 1,
|
|
'Frontend::Module###AgentTicketBulk' => 1,
|
|
'Frontend::Module###AgentTicketClose' => 1,
|
|
'Frontend::Module###AgentTicketCompose' => 1,
|
|
'Frontend::Module###AgentTicketCustomer' => 1,
|
|
'Frontend::Module###AgentTicketEmailOutbound' => 1,
|
|
'Frontend::Module###AgentTicketEmailResend' => 1,
|
|
'Frontend::Module###AgentTicketForward' => 1,
|
|
'Frontend::Module###AgentTicketFreeText' => 1,
|
|
'Frontend::Module###AgentTicketHistory' => 1,
|
|
'Frontend::Module###AgentTicketLock' => 1,
|
|
'Frontend::Module###AgentTicketMerge' => 1,
|
|
'Frontend::Module###AgentTicketMove' => 1,
|
|
'Frontend::Module###AgentTicketNote' => 1,
|
|
'Frontend::Module###AgentTicketOwner' => 1,
|
|
'Frontend::Module###AgentTicketPending' => 1,
|
|
'Frontend::Module###AgentTicketPhoneInbound' => 1,
|
|
'Frontend::Module###AgentTicketPhoneOutbound' => 1,
|
|
'Frontend::Module###AgentTicketPlain' => 1,
|
|
'Frontend::Module###AgentTicketPrint' => 1,
|
|
'Frontend::Module###AgentTicketPriority' => 1,
|
|
'Frontend::Module###AgentTicketResponsible' => 1,
|
|
'Frontend::Module###AgentTicketSMSOutbound' => 1,
|
|
'Frontend::Module###AgentTicketWatcher' => 1,
|
|
'Frontend::Module###AgentTicketZoom' => 1,
|
|
'Frontend::Module###AgentUserSearch' => 1,
|
|
'Frontend::Module###AgentVideoChat' => 1,
|
|
'Frontend::Module###AgentZoom' => 1,
|
|
'Frontend::Module###AjaxAttachment' => 1,
|
|
'Frontend::Module###Login' => 1,
|
|
'Frontend::Module###Logout' => 1,
|
|
'Frontend::Module###PictureUpload' => 1,
|
|
'PublicFrontend::Module###PublicCalendar' => 1,
|
|
'PublicFrontend::Module###PublicDefault' => 1,
|
|
'PublicFrontend::Module###PublicRepository' => 1,
|
|
'PublicFrontend::Module###PublicSupportDataCollector' => 1,
|
|
);
|
|
|
|
if ( !$NoDefaultNavigationSetting{$Name} ) {
|
|
|
|
$Name =~ s{Frontend::Module}{Frontend::Navigation}gsmx;
|
|
$Name .= '###' . ( $InitToLoaderMapping{$Init} // '005-' ) . $Param{Name};
|
|
|
|
my $Navigation = sprintf "%-*s%s", 4, "", "<Setting Name=\"$Name\" Required=\"0\" Valid=\"0\">\n";
|
|
$Navigation .= sprintf "%-*s%s", 8, "",
|
|
"<Description Translatable=\"1\">Main menu item registration.</Description>";
|
|
|
|
if ( $Setting =~ m{<SubGroup>(.*?)</SubGroup>} ) {
|
|
my $NavigationStr = $NavigationLookup{$1} || $1;
|
|
$NavigationStr .= "::MainMenu";
|
|
$Navigation .= sprintf( "\n%-*s%s", 8, "", "<Navigation>$NavigationStr</Navigation>" );
|
|
}
|
|
|
|
$Navigation .= sprintf( "\n%-*s%s", 8, "", "<Value>" );
|
|
$Navigation .= sprintf( "\n%-*s%s", 12, "", "<Array>" );
|
|
$Navigation .= sprintf( "\n%-*s%s", 16, "", "<DefaultItem ValueType=\"FrontendNavigation\">" );
|
|
$Navigation .= sprintf( "\n%-*s%s", 20, "", "<Hash>" );
|
|
$Navigation .= sprintf( "\n%-*s%s", 20, "", "</Hash>" );
|
|
$Navigation .= sprintf( "\n%-*s%s", 16, "", "</DefaultItem>" );
|
|
$Navigation .= sprintf( "\n%-*s%s", 12, "", "</Array>" );
|
|
$Navigation .= sprintf( "\n%-*s%s", 8, "", "</Value>" );
|
|
$Navigation .= sprintf( "\n%-*s%s", 4, "", "</ConfigItem>\n" ); # We rename ConfigItems later
|
|
|
|
$Setting .= "\n" . $Navigation;
|
|
}
|
|
}
|
|
|
|
if ( $NavBarModule && $Setting =~ m{<ConfigItem\s+Name="(.*?)"(.*?)>}gsmx ) {
|
|
|
|
# FrontendNavigationModule
|
|
|
|
my $Name = $1;
|
|
my $Options = $2;
|
|
|
|
$Name =~ s{Frontend::Module}{Frontend::NavigationModule}gsmx;
|
|
|
|
my $NavigationModule = sprintf "%-*s%s", 4, "", "<Setting Name=\"$Name\"$Options>\n";
|
|
$NavigationModule .= sprintf "%-*s%s", 8, "",
|
|
"<Description Translatable=\"1\">Admin area navigation for the agent interface.</Description>";
|
|
|
|
if ( $Setting =~ m{<SubGroup>(.*?)</SubGroup>} ) {
|
|
my $NavigationStr = $NavigationLookup{$1} || $1;
|
|
|
|
$NavigationStr .= '::AdminOverview';
|
|
$NavigationModule .= sprintf( "\n%-*s%s", 8, "", "<Navigation>$NavigationStr</Navigation>" );
|
|
}
|
|
|
|
$NavigationModule .= sprintf( "\n%-*s%s", 8, "", "<Value>" );
|
|
$NavigationModule .= sprintf( "\n%-*s%s", 12, "", "<Hash>" );
|
|
|
|
for my $NavBarTag (qw(Group GroupRo)) {
|
|
my @Items;
|
|
|
|
while ( $NavBarModule =~ s{<$NavBarTag>(.*?)<\/$NavBarTag}{}smx ) {
|
|
push @Items, $1;
|
|
}
|
|
|
|
$NavigationModule .= sprintf( "\n%-*s%s", 16, "", "<Item Key=\"$NavBarTag\">" );
|
|
$NavigationModule .= sprintf( "\n%-*s%s", 20, "", "<Array>" );
|
|
|
|
for my $Value (@Items) {
|
|
$NavigationModule .= sprintf( "\n%-*s%s", 24, "", "<Item>$Value</Item>" );
|
|
}
|
|
|
|
if (
|
|
!scalar @Items
|
|
&& $GroupItems{$NavBarTag}
|
|
)
|
|
{
|
|
# take group items from FrontendModuleReg
|
|
for my $Value ( @{ $GroupItems{$NavBarTag} } ) {
|
|
if ($Value) {
|
|
$NavigationModule .= sprintf( "\n%-*s%s", 24, "", "<Item>$Value</Item>" );
|
|
}
|
|
}
|
|
}
|
|
|
|
$NavigationModule .= sprintf( "\n%-*s%s", 20, "", "</Array>" );
|
|
$NavigationModule .= sprintf( "\n%-*s%s", 16, "", "</Item>" );
|
|
}
|
|
|
|
NAVBARTAG:
|
|
for my $NavBarTag (qw(Module Name Block Description IconBig IconSmall CssClass)) {
|
|
my $Value = '';
|
|
my $Attributes = '';
|
|
|
|
if ( $NavBarModule =~ m{<$NavBarTag>(.*?)<\/$NavBarTag} ) {
|
|
$Value = $1;
|
|
}
|
|
elsif ( $NavBarModule =~ m{<$NavBarTag\s(.*?)>(.*?)<\/$NavBarTag} ) {
|
|
$Attributes = " $1";
|
|
$Value = $2;
|
|
}
|
|
|
|
# special treatment for OTRSBusiness tile CssClass
|
|
if ( $NavBarTag eq 'CssClass' ) {
|
|
next NAVBARTAG if $Name ne 'Frontend::NavigationModule###AdminOTRSBusiness';
|
|
$Value = 'OTRSBusiness';
|
|
}
|
|
|
|
$NavigationModule .= sprintf(
|
|
"\n%-*s%s", 16, "",
|
|
"<Item Key=\"$NavBarTag\"$Attributes>$Value</Item>",
|
|
);
|
|
}
|
|
|
|
$NavigationModule .= sprintf( "\n%-*s%s", 12, "", "</Hash>" );
|
|
$NavigationModule .= sprintf( "\n%-*s%s", 8, "", "</Value>" );
|
|
$NavigationModule .= sprintf( "\n%-*s%s", 4, "", "</ConfigItem>\n" ); # We rename ConfigItems later
|
|
|
|
$Setting .= "\n" . $NavigationModule;
|
|
}
|
|
}
|
|
|
|
# Rename Regex to ValueRegex.
|
|
$Setting =~ s{^(\s+<String\s+)Regex="(.*?)"}{$1ValueRegex="$2"}gsmx;
|
|
|
|
# Check for known old validation modules.
|
|
for my $ValidateModule (qw(StateValidate PriorityValidate QueueValidate)) {
|
|
|
|
if ( $Setting =~ m{<ValidateModule>.*?$ValidateModule</ValidateModule>}gsm ) {
|
|
|
|
# Remove ValidateModule tag.
|
|
$Setting =~ s{^\s+<ValidateModule>.*?::$ValidateModule</ValidateModule>}{}gsmx;
|
|
|
|
my $Entity;
|
|
if ( $ValidateModule eq 'StateValidate' ) {
|
|
$Entity = 'State';
|
|
}
|
|
elsif ( $ValidateModule eq 'PriorityValidate' ) {
|
|
$Entity = 'Priority';
|
|
}
|
|
elsif ( $ValidateModule eq 'QueueValidate' ) {
|
|
$Entity = 'Queue';
|
|
}
|
|
|
|
# Update string tag.
|
|
$Setting =~ s{<String(.*?)>(.*?)</String>}
|
|
{<Item ValueType="Entity" ValueEntityType="$Entity"$1>$2</Item>}gsmx;
|
|
}
|
|
}
|
|
|
|
# Update file path.
|
|
$Setting =~ s{<String\s+ValueRegex="(.*?)"\s+Check="File".*?>(.*?)<\/String>}
|
|
{<Item ValueRegex="$1" ValueType="File">$2</Item>}gsmx;
|
|
|
|
# Update file directory.
|
|
$Setting =~ s{<String\s+ValueRegex="(.*?)"\s+Check="Directory".*?>(.*?)<\/String>}
|
|
{<Item ValueRegex="$1" ValueType="Directory">$2</Item>}gsmx;
|
|
|
|
# Replace No/Yes drop-down with Checkbox.
|
|
$Setting =~ s{
|
|
^(\s+) # match space
|
|
<Option.*?SelectedID="(\d)" # match SelectedID inside Option tag
|
|
.*? Key="0" .*?>No< # match No
|
|
.*? Key="1" .*?>Yes</Item> # match Yes
|
|
\s+?</Option>? # match end of option
|
|
}
|
|
{$1<Item ValueType="Checkbox">$2</Item>}gsmx;
|
|
$Setting =~ s{
|
|
^(\s+) # match space
|
|
<Option.*?SelectedID="" # match empty SelectedID inside Option tag
|
|
.*? Key="0" .*?>No< # match No
|
|
.*? Key="1" .*?>Yes</Item> # match Yes
|
|
\s+?</Option>? # match end of option
|
|
}
|
|
{$1<Item ValueType="Checkbox">0</Item>}gsmx;
|
|
|
|
# Replace Yes/No drop-down with Checkbox
|
|
$Setting =~ s{
|
|
^(\s+) # match space
|
|
<Option.*?SelectedID="(\d)" # match SelectedID inside Option tag
|
|
.*? Key="1" .*?>Yes< # match Yes
|
|
.*? Key="0" .*?>No</Item> # match No
|
|
\s+?</Option> # match end of option
|
|
}
|
|
{$1<Item ValueType="Checkbox">$2</Item>}gsmx;
|
|
$Setting =~ s{
|
|
^(\s+) # match space
|
|
<Option.*?SelectedID="" # match empty SelectedID inside Option tag
|
|
.*? Key="1" .*?>Yes< # match Yes
|
|
.*? Key="0" .*?>No</Item> # match No
|
|
\s+?</Option> # match end of option
|
|
}
|
|
{$1<Item ValueType="Checkbox">0</Item>}gsmx;
|
|
|
|
# Check if this Setting contains Option with Items.
|
|
if ( $Setting =~ m{<Option.*?<Item.*?</Option>}gsm ) {
|
|
my @Items = split( '</Item>', $Setting );
|
|
|
|
for my $Item (@Items) {
|
|
|
|
# Set the ValueType 'Option' tag to the main item.
|
|
$Item =~ s{<Item\s+Key="(.*?)"(.*?)>(.*?)$}{<Item ValueType="Option" Value="$1"$2>$3}gsmx;
|
|
|
|
# Convert Options to children Item.
|
|
$Item =~ s{<Option(.*?)>}{<Item ValueType="Select"$1>}gsmx;
|
|
|
|
# Convert </Option> to </Item>
|
|
$Item =~ s{</Option>}{</Item>}gsmx;
|
|
}
|
|
|
|
$Setting = join( '</Item>', @Items );
|
|
}
|
|
elsif ( $Setting =~ m{<Option\s+Location="(.*?)"\s+SelectedID="(.*?)".*?</Option>}gsm ) {
|
|
my ( $Location, $SelectedID ) = ( $1, $2 );
|
|
|
|
$Setting =~ s{<Option.*?</Option>}
|
|
{<Item ValueType="PerlModule" ValueFilter="$Location">$SelectedID</Item>}gsmx;
|
|
}
|
|
|
|
# Update WorkingHours.
|
|
if ( $Setting =~ m{TimeWorkingHours} ) {
|
|
my @Days = split( "</Day>", $Setting );
|
|
pop @Days; # contains not needed item
|
|
|
|
my $WorkingHoursString = '';
|
|
my $SpaceString = '';
|
|
|
|
for my $Day (@Days) {
|
|
|
|
# Check if this item contains string and update to WorkingHours ValueType.
|
|
if ( $Day =~ s{^(\s+)<TimeWorkingHours>}{$1<Item ValueType="WorkingHours">}gsmx ) {
|
|
if ($1) {
|
|
$SpaceString = $1;
|
|
}
|
|
}
|
|
|
|
# Set Day ValueType tag.
|
|
$Day =~ s{<Day\s+Name="(.*?)">}{<Item ValueType="Day" ValueName="$1">}gsmx;
|
|
|
|
# Set Hour ValueType tag.
|
|
$Day =~ s{<Hour>(\d+)</Hour>}{<Item ValueType="Hour">$1</Item>}gsmx;
|
|
|
|
# Add block closure tag on the last item.
|
|
if ( $Day eq $Days[-1] ) {
|
|
$Day .= "</Item>\n$SpaceString</Item>";
|
|
}
|
|
}
|
|
|
|
my $DaysString = join( '</Item>', @Days );
|
|
|
|
$Setting =~ s{.*?<TimeWorkingHours>.*?</TimeWorkingHours>}{$DaysString}gsmx;
|
|
}
|
|
|
|
# Update VacationDays.
|
|
if ( $Setting =~ m{<(TimeVacationDays.*?)>} ) {
|
|
my $Type = $1;
|
|
|
|
my $TypeNew;
|
|
if ( $Type eq 'TimeVacationDays' ) {
|
|
$TypeNew = "VacationDays";
|
|
}
|
|
else {
|
|
$TypeNew = "VacationDaysOneTime";
|
|
}
|
|
|
|
# Update item tags to the new format.
|
|
$Setting =~ s{Year=}{ValueYear=}gsmx;
|
|
$Setting =~ s{Month=}{ValueMonth=}gsmx;
|
|
$Setting =~ s{Day=}{ValueDay=}gsmx;
|
|
|
|
# Update TimeVacationDays tags.
|
|
$Setting =~ s{<$Type>}{<Item ValueType="$TypeNew">}gsmx;
|
|
$Setting =~ s{</$Type>}{</Item>}gsmx;
|
|
}
|
|
|
|
# Update DynamicField Settings
|
|
my $Hashtag = '###';
|
|
my @DFoptions;
|
|
if (
|
|
$Setting =~ m{Name=(.*?)\#\#\#(|FollowUp|ProcessWidget|SearchOverview|SearchCSV)DynamicField\"} ||
|
|
$Setting =~ m{Name=(.*?)(\#\#\#DefaultColumns|DefaultOverviewColumns)} ||
|
|
$Setting =~ m{Name=\"(AgentCustomerInformationCenter::Backend|DashboardBackend)\#\#\#} ||
|
|
$Setting =~ m{Name=\"LinkObject::ComplexTable\#\#\#Ticket\"}
|
|
)
|
|
{
|
|
|
|
# 0 = Disabled, 1 = Enabled, 2 = Enabled and shown by default
|
|
if (
|
|
$Setting
|
|
=~ m{\sPossible\ssettings:\s0\s=\sDisabled,\s1\s=\sEnabled,\s2\s=\sEnabled\sand\sshown\sby\sdefault.}
|
|
)
|
|
{
|
|
@DFoptions = ( '0 - Disabled', '1 - Enabled', '2 - Enabled and shown by default' );
|
|
$Setting
|
|
=~ s{\sPossible\ssettings:\s0\s=\sDisabled,\s1\s=\sEnabled,\s2\s=\sEnabled\sand\sshown\sby\sdefault.}{}gsmx;
|
|
}
|
|
|
|
# 0 = Disabled, 1 = Enabled, 2 = Enabled and required.
|
|
elsif (
|
|
$Setting =~ m{\sPossible\ssettings:\s0\s=\sDisabled,\s1\s=\sEnabled,\s2\s=\sEnabled\sand\srequired.}
|
|
)
|
|
{
|
|
@DFoptions = ( '0 - Disabled', '1 - Enabled', '2 - Enabled and required' );
|
|
$Setting
|
|
=~ s{\sPossible\ssettings:\s0\s=\sDisabled,\s1\s=\sEnabled,\s2\s=\sEnabled\sand\srequired.}{}gsmx;
|
|
}
|
|
|
|
# 0 = Disabled, 1 = Available, 2 = Enabled by default.
|
|
elsif (
|
|
$Setting =~ m{\sPossible\ssettings:\s0\s=\sDisabled,\s1\s=\sAvailable,\s2\s=\sEnabled\sby\sdefault.} ||
|
|
$Setting =~ m{Name=\"DashboardBackend\#\#\#0140-RunningTicketProcess\"}
|
|
)
|
|
{
|
|
@DFoptions = ( '0 - Disabled', '1 - Available', '2 - Enabled by default' );
|
|
$Setting
|
|
=~ s{\sPossible\ssettings:\s0\s=\sDisabled,\s1\s=\sAvailable,\s2\s=\sEnabled\sby\sdefault.}{}gmsx;
|
|
}
|
|
|
|
# 0 = Disabled, 1 = Enabled.
|
|
elsif (
|
|
$Setting =~ m{\sPossible\ssettings:\s0\s=\sDisabled,\s1\s=\sEnabled.}
|
|
)
|
|
{
|
|
@DFoptions = ( '0 - Disabled', '1 - Enabled' );
|
|
$Setting =~ s{\sPossible\ssettings:\s0\s=\sDisabled,\s1\s=\sEnabled.}{}gsmx;
|
|
}
|
|
my $ReplacementString;
|
|
|
|
my $DFCount = 0;
|
|
if (@DFoptions) {
|
|
$ReplacementString = "\n\t\t\t<Hash>\n" .
|
|
"\t\t\t\t<DefaultItem ValueType=\"Select\">\n";
|
|
for my $DFoption (@DFoptions) {
|
|
## nofilter(TidyAll::Plugin::OTRS::Perl::Translatable)
|
|
$ReplacementString
|
|
.= "\t\t\t\t\t<Item ValueType=\"Option\" Value=\"$DFCount\" Translatable=\"1\">$DFoption</Item>\n";
|
|
$DFCount++;
|
|
}
|
|
$ReplacementString .= "\t\t\t\t</DefaultItem>\n" .
|
|
"\t\t\t</Hash>\n";
|
|
}
|
|
|
|
if ($ReplacementString) {
|
|
|
|
# DynamicFields
|
|
$Setting =~ s{
|
|
Name=(.*?)\#\#\#(|FollowUp|ProcessWidget|SearchOverview|SearchCSV)DynamicField\"(.*?)
|
|
<Setting>(\s+)<Hash>(\s+)<\/Hash>
|
|
}{Name=$1$Hashtag$2DynamicField"$3<Value>$ReplacementString}gsmx;
|
|
|
|
# DefaultColumns
|
|
$ReplacementString =~ s{\n\t\t\t<Hash>\n}{\n\t<Hash>\n};
|
|
$ReplacementString =~ s{\n}{\n\t\t};
|
|
$ReplacementString =~ s{\t\t\t</Hash>\n}{};
|
|
$ReplacementString .= "\t\t<Item Key=\"Age\">2</Item>";
|
|
my $DefaultColumnsHashtag = $Hashtag . 'DefaultColumns';
|
|
|
|
$Setting =~ s{
|
|
Name=(.*?)\#\#\#DefaultColumns\"(.*?)
|
|
<Setting>(\s+)<Hash>(\s+)<Item\sKey=\"Age\">2</Item>
|
|
}{Name=$1$DefaultColumnsHashtag"$2<Value>$ReplacementString}gsmx;
|
|
|
|
$Setting =~ s{
|
|
Name=(.*?)DefaultOverviewColumns\"(.*?)
|
|
<Setting>(\s+)<Hash>(\s+)<Item\sKey=\"Age\">2</Item>
|
|
}{Name=$1DefaultOverviewColumns"$2<Value>$ReplacementString}gsmx;
|
|
|
|
# AgentCustomerInformationCenter-||DashboardBackend
|
|
my $BackendReplacement = "<Item Key=\"DefaultColumns\">" .
|
|
$ReplacementString . "\n";
|
|
$BackendReplacement =~ s{\n\t}{\n\t\t\t}gsmx;
|
|
$Setting =~ s{
|
|
Name=\"(DashboardBackend|AgentCustomerInformationCenter::Backend)\#\#\#(.*?)\"(.*?)
|
|
<Item\sKey=\"DefaultColumns\">(\s+)<Hash>(\s+)<Item\sKey=\"Age\">2</Item>
|
|
}
|
|
{Name="$1$Hashtag$2"$3$BackendReplacement}gsmx;
|
|
|
|
if ( $Setting =~ m{Name=\"LinkObject::ComplexTable\#\#\#Ticket\"} ) {
|
|
my $LinkBackendReplace = $BackendReplacement;
|
|
$LinkBackendReplace =~ s{DefaultItem>(\s+)<Item\sKey}{DefaultItem>\n\t\t\t\t\t\t<Item Key}gsmx;
|
|
$LinkBackendReplace =~ s{\t\t<Item\sKey=\"Age\">2</Item>}{<Item Key="Age">1</Item>}gsmx;
|
|
$Setting =~ s{
|
|
<Item\sKey=\"DefaultColumns\">(\s+)<Hash>(\s+)<Item\sKey=\"Age\">1</Item>
|
|
}
|
|
{$LinkBackendReplace}gsmx;
|
|
}
|
|
|
|
# Fill dropdowns with existing values.
|
|
$Setting =~ s{<\/DefaultItem>(\s*?)<Item\sKey="(.*?)">(0|1|2)<}
|
|
{<\/DefaultItem>$1\t\t<Item Key="$2" SelectedID="$3"><}gsmx;
|
|
|
|
# Only alter <Items> right after </DefaultItem> and before the closing the hash </Hash>
|
|
my $DropdownItems;
|
|
if ( $Setting =~ m{<\/DefaultItem>(.+)<\/Hash>\s+^[\s]}smx ) {
|
|
|
|
$DropdownItems = $1;
|
|
|
|
while (
|
|
$DropdownItems =~ m{"(0|1|2)"><\/Item>(\s*)<Item\sKey="(.*?)">(0|1|2)<}
|
|
)
|
|
{
|
|
if ( $2 ne 'Default' ) {
|
|
$DropdownItems =~ s{><\/Item>(\s*)<Item\sKey="(.*?)">(0|1|2)<}
|
|
{></Item>$1<Item Key="$2" SelectedID="$3"><}gsmx;
|
|
}
|
|
}
|
|
|
|
$DropdownItems =~ s{><\/Item>(\s*)<Item\sKey="Default"\sSelectedID="(0|1)"><}
|
|
{></Item>\n\t\t\t\t<Item Key="Default">$2<}gsmx;
|
|
}
|
|
|
|
if ($DropdownItems) {
|
|
$Setting =~ s{(<\/DefaultItem>).+(<\/Hash>\s+^[\s])}{$1$DropdownItems$2}msx;
|
|
}
|
|
|
|
# replace tab with spaces
|
|
$Setting =~ s{\t}{ }gsmx;
|
|
|
|
# FAQ.xml
|
|
# LinkObject::ComplexTable###FAQ
|
|
|
|
# ITSMTicket.xml
|
|
# Ticket::Frontend::AgentTicketAddtlITSMField###DynamicField
|
|
# Ticket::Frontend::AgentTicketDecision###DynamicField
|
|
|
|
# TicketITSMTicket.xml
|
|
# Ticket::Frontend::AgentTicketPhone###DynamicField
|
|
# Ticket::Frontend::AgentTicketEmail###DynamicField
|
|
# Ticket::Frontend::AgentTicketSearch###DynamicField
|
|
# Ticket::Frontend::AgentTicketZoom###DynamicField
|
|
# Ticket::Frontend::AgentTicketPriority###DynamicField
|
|
# Ticket::Frontend::AgentTicketClose###DynamicField
|
|
# Ticket::Frontend::AgentTicketCompose###DynamicField
|
|
# Ticket::Frontend::CustomerTicketZoom###DynamicField
|
|
}
|
|
}
|
|
|
|
# get the needed ArticleTypeMapping from a YML file
|
|
my $TaskConfig = $Self->GetTaskConfig( Module => 'MigrateArticleData' );
|
|
my %ArticleTypeMapping = %{ $TaskConfig->{ArticleTypeMapping} };
|
|
|
|
# Migrate Postmaster settings for
|
|
# PostMaster::PreFilterModule
|
|
# PostMaster::PreCreateFilterModule
|
|
# PostMaster::PostFilterModule
|
|
# PostMaster::CheckFollowUpModule
|
|
if (
|
|
$Setting =~ m{ Name="PostMaster::(PreFilter|PreCreateFilter|PostFilter|CheckFollowUp)Module\#\#\# .+ }xms
|
|
)
|
|
{
|
|
$Setting
|
|
=~ s{<Item Key="X-OTRS-ArticleType">(.*?)</Item>}{<Item Key="X-OTRS-IsVisibleForCustomer">$ArticleTypeMapping{$1}->{Visible}</Item>}g;
|
|
$Setting
|
|
=~ s{<Item Key="X-OTRS-FollowUp-ArticleType">(.*?)</Item>}{<Item Key="X-OTRS-FollowUp-IsVisibleForCustomer">$ArticleTypeMapping{$1}->{Visible}</Item>}g;
|
|
$Setting
|
|
=~ s{<Item Key="ArticleType"[^>]*>(.*?)</Item>}{<Item Key="IsVisibleForCustomer" Translatable="1">$ArticleTypeMapping{$1}->{Visible}</Item>}g;
|
|
$Setting
|
|
=~ s{<Item Key="Module">Kernel::System::PostMaster::Filter::FollowUpArticleTypeCheck</Item>}{<Item Key="Module">Kernel::System::PostMaster::Filter::FollowUpArticleVisibilityCheck</Item>}g;
|
|
}
|
|
|
|
# Remove Group.
|
|
$Setting =~ s{\s+<Group>(.*?)</Group>}{}gsmx;
|
|
|
|
# Update SubGroup to the Navigation.
|
|
$Setting =~ s{SubGroup>}{Navigation>}gsmx;
|
|
|
|
my @NavigationValues = $Setting =~ m{<Navigation>(.*?)</Navigation>}g;
|
|
if ( scalar @NavigationValues ) {
|
|
my $NavigationValue = $NavigationValues[0];
|
|
my $NavigationStr = $NavigationLookup{$NavigationValue} || $NavigationValue;
|
|
|
|
if (
|
|
scalar @NavigationValues < 2
|
|
|| !grep { $NavigationStr eq $_ } (
|
|
'Frontend::Admin::ModuleRegistration',
|
|
'Frontend::Agent::ModuleRegistration',
|
|
'Frontend::Customer::ModuleRegistration',
|
|
)
|
|
)
|
|
{
|
|
$Setting =~ s{<Navigation>.*?</Navigation>}{<Navigation>$NavigationStr</Navigation>}gsmx;
|
|
}
|
|
}
|
|
|
|
# Update Setting to the Value.
|
|
$Setting =~ s{Setting>}{Value>}gsmx;
|
|
|
|
# # Add missing RegEx to all Numbers
|
|
$Setting =~ s{<String>(\d+)</String>$}
|
|
{<Item ValueType="String" ValueRegex="^\\d+\$">$1</Item>}gsmx;
|
|
|
|
$Setting =~ s{<String\sValueRegex="">(\d+)</String>}
|
|
{<Item ValueType="String" ValueRegex="^\\d+\$">$1</Item>}gsmx;
|
|
|
|
$Setting =~ s{<String\sValueRegex="\\d\+">(\d+?)</String>}
|
|
{<Item ValueType="String" ValueRegex="^\\d+\$">$1</Item>}gsmx;
|
|
|
|
$Setting =~ s{<String\sValueRegex="\[(.*?)">(\d+)</String>}
|
|
{<Item ValueType="String" ValueRegex="^[$1">$2</Item>}gmsx;
|
|
|
|
# Update string and text-area to items with its corresponding ValueType.
|
|
$Setting =~ s{<TextArea(.*?)</TextArea>}{<Item ValueType="Textarea"$1</Item>}gsmx;
|
|
$Setting =~ s{<String(.*?)</String>}{<Item ValueType="String"$1</Item>}gsmx;
|
|
|
|
# Convert password strings
|
|
$Setting =~ s{<Item\sValueType="String"(.*?)Type="Password"(.*?)$}
|
|
{<Item ValueType="Password"$2}gsmx;
|
|
$Setting =~ s{<Item\sKey="Password">(.*?)$}
|
|
{<Item Key="Password" ValueType="Password">$1}gsmx;
|
|
|
|
# Convert TicketType to Entity
|
|
$Setting =~ s{<Item\sValueType="String"\sValueRegex=""(.*?)>Unclassified(.*?)$}
|
|
{<Item ValueType="Entity" ValueEntityType="Type"$1>Unclassified$2}gsmx;
|
|
|
|
$Setting =~ m{<ConfigItem\sName="(.*?)"}gsmx;
|
|
my $SettingName = $1;
|
|
|
|
my @SettingsUserModificationPossible = (
|
|
'Frontend::Admin::AdminNotificationEvent###RichTextHeight',
|
|
'Frontend::Admin::AdminNotificationEvent###RichTextWidth',
|
|
'Frontend::CustomerUser::Item###1-GoogleMaps',
|
|
'Frontend::CustomerUser::Item###15-OpenTickets',
|
|
'Frontend::CustomerUser::Item###16-OpenTicketsForCustomerUserLogin',
|
|
'Frontend::CustomerUser::Item###17-ClosedTickets',
|
|
'Frontend::CustomerUser::Item###18-ClosedTicketsForCustomerUserLogin',
|
|
'Frontend::CustomerUser::Item###2-Google',
|
|
'Frontend::CustomerUser::Item###2-LinkedIn',
|
|
'Frontend::CustomerUser::Item###3-XING',
|
|
'Frontend::ToolBarModule###110-Ticket::AgentTicketQueue',
|
|
'Frontend::ToolBarModule###120-Ticket::AgentTicketStatus',
|
|
'Frontend::ToolBarModule###130-Ticket::AgentTicketEscalation',
|
|
'Frontend::ToolBarModule###140-Ticket::AgentTicketPhone',
|
|
'Frontend::ToolBarModule###150-Ticket::AgentTicketEmail',
|
|
'Frontend::ToolBarModule###160-Ticket::AgentTicketProcess',
|
|
'Frontend::ToolBarModule###210-Ticket::TicketSearchProfile',
|
|
'Frontend::ToolBarModule###220-Ticket::TicketSearchFulltext',
|
|
'Frontend::ToolBarModule###230-CICSearchCustomerID',
|
|
'Frontend::ToolBarModule###240-CICSearchCustomerUser',
|
|
'Ticket::Frontend::AgentTicketBounce###StateDefault',
|
|
'Ticket::Frontend::AgentTicketBulk###ArticleTypeDefault',
|
|
'Ticket::Frontend::AgentTicketBulk###Owner',
|
|
'Ticket::Frontend::AgentTicketBulk###Priority',
|
|
'Ticket::Frontend::AgentTicketBulk###PriorityDefault',
|
|
'Ticket::Frontend::AgentTicketBulk###Responsible',
|
|
'Ticket::Frontend::AgentTicketBulk###State',
|
|
'Ticket::Frontend::AgentTicketBulk###StateDefault',
|
|
'Ticket::Frontend::AgentTicketBulk###TicketType',
|
|
'Ticket::Frontend::AgentTicketClose###ArticleTypeDefault',
|
|
'Ticket::Frontend::AgentTicketClose###Body',
|
|
'Ticket::Frontend::AgentTicketClose###InformAgent',
|
|
'Ticket::Frontend::AgentTicketClose###InvolvedAgent',
|
|
'Ticket::Frontend::AgentTicketClose###Note',
|
|
'Ticket::Frontend::AgentTicketClose###NoteMandatory',
|
|
'Ticket::Frontend::AgentTicketClose###Owner',
|
|
'Ticket::Frontend::AgentTicketClose###OwnerMandatory',
|
|
'Ticket::Frontend::AgentTicketClose###Priority',
|
|
'Ticket::Frontend::AgentTicketClose###PriorityDefault',
|
|
'Ticket::Frontend::AgentTicketClose###Queue',
|
|
'Ticket::Frontend::AgentTicketClose###Responsible',
|
|
'Ticket::Frontend::AgentTicketClose###ResponsibleMandatory',
|
|
'Ticket::Frontend::AgentTicketClose###RichTextHeight',
|
|
'Ticket::Frontend::AgentTicketClose###RichTextWidth',
|
|
'Ticket::Frontend::AgentTicketClose###Service',
|
|
'Ticket::Frontend::AgentTicketClose###ServiceMandatory',
|
|
'Ticket::Frontend::AgentTicketClose###SLAMandatory',
|
|
'Ticket::Frontend::AgentTicketClose###State',
|
|
'Ticket::Frontend::AgentTicketClose###StateDefault',
|
|
'Ticket::Frontend::AgentTicketClose###Subject',
|
|
'Ticket::Frontend::AgentTicketClose###TicketType',
|
|
'Ticket::Frontend::AgentTicketClose###Title',
|
|
'Ticket::Frontend::AgentTicketCompose###DefaultArticleType',
|
|
'Ticket::Frontend::AgentTicketCompose###StateDefault',
|
|
'Ticket::Frontend::AgentTicketCustomer::CustomerIDReadOnly',
|
|
'Ticket::Frontend::AgentTicketEmail::CustomerIDReadOnly',
|
|
'Ticket::Frontend::AgentTicketEmail###ArticleType',
|
|
'Ticket::Frontend::AgentTicketEmail###Body',
|
|
'Ticket::Frontend::AgentTicketEmail###Priority',
|
|
'Ticket::Frontend::AgentTicketEmail###RichTextHeight',
|
|
'Ticket::Frontend::AgentTicketEmail###RichTextWidth',
|
|
'Ticket::Frontend::AgentTicketEmail###ServiceMandatory',
|
|
'Ticket::Frontend::AgentTicketEmail###SLAMandatory',
|
|
'Ticket::Frontend::AgentTicketEmail###StateDefault',
|
|
'Ticket::Frontend::AgentTicketEmail###Subject',
|
|
'Ticket::Frontend::AgentTicketEmailOutbound###ArticleTypeDefault',
|
|
'Ticket::Frontend::AgentTicketEmailOutbound###RichTextHeight',
|
|
'Ticket::Frontend::AgentTicketEmailOutbound###RichTextWidth',
|
|
'Ticket::Frontend::AgentTicketEmailOutbound###StateDefault',
|
|
'Ticket::Frontend::AgentTicketEscalationView###Order::Default',
|
|
'Ticket::Frontend::AgentTicketEscalationView###SortBy::Default',
|
|
'Ticket::Frontend::AgentTicketForward###ArticleTypeDefault',
|
|
'Ticket::Frontend::AgentTicketForward###RichTextHeight',
|
|
'Ticket::Frontend::AgentTicketForward###RichTextWidth',
|
|
'Ticket::Frontend::AgentTicketForward###StateDefault',
|
|
'Ticket::Frontend::AgentTicketFreeText###ArticleTypeDefault',
|
|
'Ticket::Frontend::AgentTicketFreeText###Body',
|
|
'Ticket::Frontend::AgentTicketFreeText###InformAgent',
|
|
'Ticket::Frontend::AgentTicketFreeText###InvolvedAgent',
|
|
'Ticket::Frontend::AgentTicketFreeText###Note',
|
|
'Ticket::Frontend::AgentTicketFreeText###NoteMandatory',
|
|
'Ticket::Frontend::AgentTicketFreeText###Owner',
|
|
'Ticket::Frontend::AgentTicketFreeText###OwnerMandatory',
|
|
'Ticket::Frontend::AgentTicketFreeText###Priority',
|
|
'Ticket::Frontend::AgentTicketFreeText###PriorityDefault',
|
|
'Ticket::Frontend::AgentTicketFreeText###Queue',
|
|
'Ticket::Frontend::AgentTicketFreeText###Responsible',
|
|
'Ticket::Frontend::AgentTicketFreeText###ResponsibleMandatory',
|
|
'Ticket::Frontend::AgentTicketFreeText###RichTextHeight',
|
|
'Ticket::Frontend::AgentTicketFreeText###RichTextWidth',
|
|
'Ticket::Frontend::AgentTicketFreeText###Service',
|
|
'Ticket::Frontend::AgentTicketFreeText###ServiceMandatory',
|
|
'Ticket::Frontend::AgentTicketFreeText###SLAMandatory',
|
|
'Ticket::Frontend::AgentTicketFreeText###State',
|
|
'Ticket::Frontend::AgentTicketFreeText###StateDefault',
|
|
'Ticket::Frontend::AgentTicketFreeText###Subject',
|
|
'Ticket::Frontend::AgentTicketFreeText###TicketType',
|
|
'Ticket::Frontend::AgentTicketFreeText###Title',
|
|
'Ticket::Frontend::AgentTicketLockedView###Order::Default',
|
|
'Ticket::Frontend::AgentTicketLockedView###SortBy::Default',
|
|
'Ticket::Frontend::AgentTicketMerge###RichTextHeight',
|
|
'Ticket::Frontend::AgentTicketMerge###RichTextWidth',
|
|
'Ticket::Frontend::AgentTicketMove###Body',
|
|
'Ticket::Frontend::AgentTicketMove###NextScreen',
|
|
'Ticket::Frontend::AgentTicketMove###Note',
|
|
'Ticket::Frontend::AgentTicketMove###NoteMandatory',
|
|
'Ticket::Frontend::AgentTicketMove###Priority',
|
|
'Ticket::Frontend::AgentTicketMove###RichTextHeight',
|
|
'Ticket::Frontend::AgentTicketMove###RichTextWidth',
|
|
'Ticket::Frontend::AgentTicketMove###State',
|
|
'Ticket::Frontend::AgentTicketMove###Subject',
|
|
'Ticket::Frontend::AgentTicketNote###ArticleTypeDefault',
|
|
'Ticket::Frontend::AgentTicketNote###Body',
|
|
'Ticket::Frontend::AgentTicketNote###InformAgent',
|
|
'Ticket::Frontend::AgentTicketNote###InvolvedAgent',
|
|
'Ticket::Frontend::AgentTicketNote###Note',
|
|
'Ticket::Frontend::AgentTicketNote###NoteMandatory',
|
|
'Ticket::Frontend::AgentTicketNote###Owner',
|
|
'Ticket::Frontend::AgentTicketNote###OwnerMandatory',
|
|
'Ticket::Frontend::AgentTicketNote###Priority',
|
|
'Ticket::Frontend::AgentTicketNote###PriorityDefault',
|
|
'Ticket::Frontend::AgentTicketNote###Queue',
|
|
'Ticket::Frontend::AgentTicketNote###Responsible',
|
|
'Ticket::Frontend::AgentTicketNote###ResponsibleMandatory',
|
|
'Ticket::Frontend::AgentTicketNote###RichTextHeight',
|
|
'Ticket::Frontend::AgentTicketNote###RichTextWidth',
|
|
'Ticket::Frontend::AgentTicketNote###Service',
|
|
'Ticket::Frontend::AgentTicketNote###ServiceMandatory',
|
|
'Ticket::Frontend::AgentTicketNote###SLAMandatory',
|
|
'Ticket::Frontend::AgentTicketNote###State',
|
|
'Ticket::Frontend::AgentTicketNote###StateDefault',
|
|
'Ticket::Frontend::AgentTicketNote###Subject',
|
|
'Ticket::Frontend::AgentTicketNote###TicketType',
|
|
'Ticket::Frontend::AgentTicketNote###Title',
|
|
'Ticket::Frontend::AgentTicketQueue###Blink',
|
|
'Ticket::Frontend::AgentTicketQueue###HideEmptyQueues',
|
|
'Ticket::Frontend::AgentTicketQueue###HighlightAge1',
|
|
'Ticket::Frontend::AgentTicketQueue###HighlightAge2',
|
|
'Ticket::Frontend::AgentTicketQueue###Order::Default',
|
|
'Ticket::Frontend::AgentTicketQueue###QueueSort',
|
|
'Ticket::Frontend::AgentTicketQueue###SortBy::Default',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###ArticleCreateTimePoint',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###ArticleCreateTimeSlot',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###MIMEBase_Body',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###MIMEBase_Cc',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###CustomerID',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###CustomerUserLogin',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###DynamicField',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###MIMEBase_From',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###Fulltext',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###QueueIDs',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###SearchInArchive',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###StateIDs',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###MIMEBase_Subject',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketChangeTimePoint',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketChangeTimeSlot',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketCloseTimePoint',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketCloseTimeSlot',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketCreateTimePoint',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketCreateTimeSlot',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketEscalationTimePoint',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketEscalationTimeSlot',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketNumber',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###Title',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###MIMEBase_To',
|
|
'Ticket::Frontend::AgentTicketSearch###Order::Default',
|
|
'Ticket::Frontend::AgentTicketSearch###SortBy::Default',
|
|
'Ticket::Frontend::AgentTicketService###Order::Default',
|
|
'Ticket::Frontend::AgentTicketService###SortBy::Default',
|
|
'Ticket::Frontend::AgentTicketStatusView###Order::Default',
|
|
'Ticket::Frontend::AgentTicketStatusView###SortBy::Default',
|
|
'Ticket::Frontend::AgentTicketWatchView###Order::Default',
|
|
'Ticket::Frontend::AgentTicketWatchView###SortBy::Default',
|
|
'Ticket::Frontend::AgentTicketZoom###ProcessDisplay',
|
|
'Ticket::Frontend::HTMLArticleHeightDefault',
|
|
'Ticket::Frontend::HTMLArticleHeightMax',
|
|
'Ticket::Frontend::MaxArticlesPerPage',
|
|
'Ticket::Frontend::PendingDiffTime',
|
|
'Ticket::Frontend::PlainView',
|
|
'Ticket::Frontend::TicketArticleFilter',
|
|
'Ticket::Frontend::ZoomCollectMeta',
|
|
'Ticket::Frontend::ZoomExpandSort',
|
|
'Ticket::Frontend::ZoomRichTextForce',
|
|
'Ticket::UseArticleColors',
|
|
'Ticket::ZoomTimeDisplay',
|
|
'TimeInputFormat',
|
|
);
|
|
|
|
if ( grep { $SettingName eq $_ } @SettingsUserModificationPossible ) {
|
|
$Setting =~ s{(ConfigItem\sName=".*?")}{$1 UserModificationPossible="1"}gsmx;
|
|
}
|
|
|
|
my @SettingsUserModificationActive = (
|
|
'Frontend::ToolBarModule###110-Ticket::AgentTicketQueue',
|
|
'Frontend::ToolBarModule###120-Ticket::AgentTicketStatus',
|
|
'Frontend::ToolBarModule###130-Ticket::AgentTicketEscalation',
|
|
'Frontend::ToolBarModule###140-Ticket::AgentTicketPhone',
|
|
'Frontend::ToolBarModule###150-Ticket::AgentTicketEmail',
|
|
'Frontend::ToolBarModule###160-Ticket::AgentTicketProcess',
|
|
'Frontend::ToolBarModule###210-Ticket::TicketSearchProfile',
|
|
'Frontend::ToolBarModule###230-CICSearchCustomerID',
|
|
'Frontend::ToolBarModule###240-CICSearchCustomerUser',
|
|
'Ticket::Frontend::AgentTicketEscalationView###Order::Default',
|
|
'Ticket::Frontend::AgentTicketEscalationView###SortBy::Default',
|
|
'Ticket::Frontend::AgentTicketLockedView###Order::Default',
|
|
'Ticket::Frontend::AgentTicketLockedView###SortBy::Default',
|
|
'Ticket::Frontend::AgentTicketMove###NextScreen',
|
|
'Ticket::Frontend::AgentTicketQueue###Blink',
|
|
'Ticket::Frontend::AgentTicketQueue###HideEmptyQueues',
|
|
'Ticket::Frontend::AgentTicketQueue###Order::Default',
|
|
'Ticket::Frontend::AgentTicketQueue###QueueSort',
|
|
'Ticket::Frontend::AgentTicketQueue###SortBy::Default',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###ArticleCreateTimePoint',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###ArticleCreateTimeSlot',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###MIMEBase_Body',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###MIMEBase_Cc',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###CustomerID',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###CustomerUserLogin',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###DynamicField',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###MIMEBase_From',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###Fulltext',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###QueueIDs',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###SearchInArchive',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###StateIDs',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###MIMEBase_Subject',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketChangeTimePoint',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketChangeTimeSlot',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketCloseTimePoint',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketCloseTimeSlot',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketCreateTimePoint',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketCreateTimeSlot',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketEscalationTimePoint',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketEscalationTimeSlot',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketNumber',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###Title',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###MIMEBase_To',
|
|
'Ticket::Frontend::AgentTicketSearch###Order::Default',
|
|
'Ticket::Frontend::AgentTicketSearch###SortBy::Default',
|
|
'Ticket::Frontend::AgentTicketService###Order::Default',
|
|
'Ticket::Frontend::AgentTicketService###SortBy::Default',
|
|
'Ticket::Frontend::AgentTicketStatusView###Order::Default',
|
|
'Ticket::Frontend::AgentTicketStatusView###SortBy::Default',
|
|
'Ticket::Frontend::AgentTicketWatchView###Order::Default',
|
|
'Ticket::Frontend::AgentTicketWatchView###SortBy::Default',
|
|
'Ticket::Frontend::PendingDiffTime',
|
|
'Ticket::Frontend::ZoomExpandSort',
|
|
'Ticket::ZoomTimeDisplay',
|
|
);
|
|
|
|
if ( grep { $SettingName eq $_ } @SettingsUserModificationActive ) {
|
|
$Setting =~ s{(ConfigItem\sName=".*?")}{$1 UserModificationActive="1"}gsmx;
|
|
}
|
|
|
|
my @SettingsToDisable = (
|
|
'PGP::Bin',
|
|
'SMIME::Bin',
|
|
'SMIME::CertPath',
|
|
'SMIME::PrivatePath',
|
|
);
|
|
|
|
if ( grep { $SettingName eq $_ } @SettingsToDisable ) {
|
|
$Setting =~ s{(ConfigItem\sName=".*?"\sRequired=)"1"(\sValid=)"1"}{$1"0"$2"0"}gsmx;
|
|
}
|
|
|
|
my %SettingsUserPreferencesGroup = (
|
|
'Frontend::Admin::AdminNotificationEvent###RichTextHeight' => 'Advanced',
|
|
'Frontend::Admin::AdminNotificationEvent###RichTextWidth' => 'Advanced',
|
|
'Frontend::CustomerUser::Item###1-GoogleMaps' => 'Advanced',
|
|
'Frontend::CustomerUser::Item###15-OpenTickets' => 'Advanced',
|
|
'Frontend::CustomerUser::Item###16-OpenTicketsForCustomerUserLogin' => 'Advanced',
|
|
'Frontend::CustomerUser::Item###17-ClosedTickets' => 'Advanced',
|
|
'Frontend::CustomerUser::Item###18-ClosedTicketsForCustomerUserLogin' => 'Advanced',
|
|
'Frontend::CustomerUser::Item###2-Google' => 'Advanced',
|
|
'Frontend::CustomerUser::Item###2-LinkedIn' => 'Advanced',
|
|
'Frontend::CustomerUser::Item###3-XING' => 'Advanced',
|
|
'Frontend::ToolBarModule###110-Ticket::AgentTicketQueue' => 'Advanced',
|
|
'Frontend::ToolBarModule###120-Ticket::AgentTicketStatus' => 'Advanced',
|
|
'Frontend::ToolBarModule###130-Ticket::AgentTicketEscalation' => 'Advanced',
|
|
'Frontend::ToolBarModule###140-Ticket::AgentTicketPhone' => 'Advanced',
|
|
'Frontend::ToolBarModule###150-Ticket::AgentTicketEmail' => 'Advanced',
|
|
'Frontend::ToolBarModule###160-Ticket::AgentTicketProcess' => 'Advanced',
|
|
'Frontend::ToolBarModule###210-Ticket::TicketSearchProfile' => 'Advanced',
|
|
'Frontend::ToolBarModule###220-Ticket::TicketSearchFulltext' => 'Advanced',
|
|
'Frontend::ToolBarModule###230-CICSearchCustomerID' => 'Advanced',
|
|
'Frontend::ToolBarModule###240-CICSearchCustomerUser' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketBounce###StateDefault' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketBulk###ArticleTypeDefault' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketBulk###Owner' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketBulk###Priority' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketBulk###PriorityDefault' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketBulk###Responsible' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketBulk###State' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketBulk###StateDefault' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketBulk###TicketType' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketClose###ArticleTypeDefault' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketClose###Body' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketClose###InformAgent' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketClose###InvolvedAgent' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketClose###Note' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketClose###NoteMandatory' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketClose###Owner' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketClose###OwnerMandatory' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketClose###Priority' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketClose###PriorityDefault' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketClose###Queue' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketClose###Responsible' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketClose###ResponsibleMandatory' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketClose###RichTextHeight' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketClose###RichTextWidth' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketClose###Service' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketClose###ServiceMandatory' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketClose###SLAMandatory' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketClose###State' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketClose###StateDefault' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketClose###Subject' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketClose###TicketType' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketClose###Title' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketCompose###DefaultArticleType' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketCompose###StateDefault' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketCustomer::CustomerIDReadOnly' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketEmail::CustomerIDReadOnly' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketEmail###ArticleType' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketEmail###Body' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketEmail###Priority' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketEmail###RichTextHeight' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketEmail###RichTextWidth' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketEmail###ServiceMandatory' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketEmail###SLAMandatory' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketEmail###StateDefault' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketEmail###Subject' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketEmailOutbound###ArticleTypeDefault' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketEmailOutbound###RichTextHeight' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketEmailOutbound###RichTextWidth' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketEmailOutbound###StateDefault' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketEscalationView###Order::Default' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketEscalationView###SortBy::Default' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketForward###ArticleTypeDefault' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketForward###RichTextHeight' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketForward###RichTextWidth' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketForward###StateDefault' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketFreeText###ArticleTypeDefault' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketFreeText###Body' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketFreeText###InformAgent' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketFreeText###InvolvedAgent' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketFreeText###Note' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketFreeText###NoteMandatory' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketFreeText###Owner' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketFreeText###OwnerMandatory' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketFreeText###Priority' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketFreeText###PriorityDefault' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketFreeText###Queue' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketFreeText###Responsible' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketFreeText###ResponsibleMandatory' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketFreeText###RichTextHeight' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketFreeText###RichTextWidth' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketFreeText###Service' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketFreeText###ServiceMandatory' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketFreeText###SLAMandatory' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketFreeText###State' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketFreeText###StateDefault' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketFreeText###Subject' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketFreeText###TicketType' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketFreeText###Title' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketLockedView###Order::Default' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketLockedView###SortBy::Default' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketMerge###RichTextHeight' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketMerge###RichTextWidth' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketMove###Body' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketMove###NextScreen' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketMove###Note' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketMove###NoteMandatory' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketMove###Priority' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketMove###RichTextHeight' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketMove###RichTextWidth' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketMove###State' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketMove###Subject' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketNote###ArticleTypeDefault' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketNote###Body' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketNote###InformAgent' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketNote###InvolvedAgent' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketNote###Note' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketNote###NoteMandatory' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketNote###Owner' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketNote###OwnerMandatory' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketNote###Priority' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketNote###PriorityDefault' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketNote###Queue' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketNote###Responsible' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketNote###ResponsibleMandatory' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketNote###RichTextHeight' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketNote###RichTextWidth' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketNote###Service' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketNote###ServiceMandatory' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketNote###SLAMandatory' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketNote###State' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketNote###StateDefault' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketNote###Subject' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketNote###TicketType' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketNote###Title' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketQueue###Blink' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketQueue###HideEmptyQueues' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketQueue###HighlightAge1' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketQueue###HighlightAge2' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketQueue###Order::Default' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketQueue###QueueSort' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketQueue###SortBy::Default' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###ArticleCreateTimePoint' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###ArticleCreateTimeSlot' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###MIMEBase_Body' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###MIMEBase_Cc' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###CustomerID' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###CustomerUserLogin' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###DynamicField' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###MIMEBase_From' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###Fulltext' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###QueueIDs' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###SearchInArchive' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###StateIDs' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###MIMEBase_Subject' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketChangeTimePoint' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketChangeTimeSlot' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketCloseTimePoint' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketCloseTimeSlot' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketCreateTimePoint' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketCreateTimeSlot' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketEscalationTimePoint' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketEscalationTimeSlot' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###TicketNumber' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###Title' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###MIMEBase_To' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###Order::Default' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketSearch###SortBy::Default' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketService###Order::Default' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketService###SortBy::Default' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketStatusView###Order::Default' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketStatusView###SortBy::Default' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketWatchView###Order::Default' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketWatchView###SortBy::Default' => 'Advanced',
|
|
'Ticket::Frontend::AgentTicketZoom###ProcessDisplay' => 'Advanced',
|
|
'Ticket::Frontend::HTMLArticleHeightDefault' => 'Advanced',
|
|
'Ticket::Frontend::HTMLArticleHeightMax' => 'Advanced',
|
|
'Ticket::Frontend::MaxArticlesPerPage' => 'Advanced',
|
|
'Ticket::Frontend::PendingDiffTime' => 'Advanced',
|
|
'Ticket::Frontend::PlainView' => 'Advanced',
|
|
'Ticket::Frontend::TicketArticleFilter' => 'Advanced',
|
|
'Ticket::Frontend::ZoomCollectMeta' => 'Advanced',
|
|
'Ticket::Frontend::ZoomExpandSort' => 'Advanced',
|
|
'Ticket::Frontend::ZoomRichTextForce' => 'Advanced',
|
|
'Ticket::UseArticleColors' => 'Advanced',
|
|
'Ticket::ZoomTimeDisplay' => 'Advanced',
|
|
'TimeInputFormat' => 'Advanced',
|
|
);
|
|
|
|
if ( $SettingsUserPreferencesGroup{$SettingName} ) {
|
|
$Setting
|
|
=~ s{(ConfigItem\sName=".*?")}{$1 UserPreferencesGroup="$SettingsUserPreferencesGroup{$SettingName}"}gsmx;
|
|
}
|
|
|
|
if ( $Setting =~ m{Name=\"DashboardBackend\#\#\#} ) {
|
|
$Setting =~ s{\n([ ]*)(<\/Hash>\n[ ]*<\/Value>)}{\n$1 <Item Key="Mandatory">0</Item>\n$1$2}xms;
|
|
}
|
|
}
|
|
|
|
my $Result = join( "", @Settings );
|
|
|
|
# Rename ConfigItem to Setting.
|
|
$Result =~ s{<ConfigItem}{<Setting}gsmx;
|
|
$Result =~ s{</ConfigItem}{</Setting}gsmx;
|
|
|
|
# Remove empty lines
|
|
$Result =~ s{>\n\n\s}{>\n }gsmx;
|
|
|
|
# Remove white space at the end of the file
|
|
$Result =~ s{</otrs_config>.*}{</otrs_config>}gsmx;
|
|
|
|
# Add new line at the end
|
|
$Result .= "\n";
|
|
|
|
return $Result;
|
|
}
|
|
|
|
=head2 MigrateConfigEffectiveValues()
|
|
|
|
Migrate the configs effective values to the new format for OTRS 6.
|
|
|
|
my $Result = $SysConfigMigrationObject->MigrateConfigEffectiveValues(
|
|
FileClass => $FileClass,
|
|
FilePath => $FilePath,
|
|
NoOutput => 1, # ( 0 | 1 ) optional, default 0.
|
|
# if set to 1 no info output will be printed to the screen.
|
|
PackageSettings => [ # (optional) only migrate the given package settings
|
|
'Frontend::Module###AdminGeneralCatalog',
|
|
'Frontend::NavigationModule###AdminGeneralCatalog',
|
|
'GeneralCatalogPreferences###Comment2',
|
|
'GeneralCatalogPreferences###Permissions',
|
|
'Loader::Agent::CommonJS###100-GeneralCatalog'
|
|
],
|
|
PackageLookupNewConfigName => {
|
|
'Ticket::EventModulePost###999-GenericInterface' => 'Ticket::EventModulePost###9900-GenericInterface',
|
|
},
|
|
ReturnMigratedSettingsCounts => 1, # (optional) returns an array with counts of un/successful migrated settings
|
|
);
|
|
|
|
Returns:
|
|
|
|
$Result = 1; # True on success or false on error.
|
|
# or
|
|
# if ReturnMigratedSettingsCounts parameter is set
|
|
$Result = {
|
|
AllSettingsCount => 1,
|
|
MissingSettings => [],
|
|
UnsuccessfullSettings => [],
|
|
};
|
|
|
|
=cut
|
|
|
|
sub MigrateConfigEffectiveValues {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
for my $Needed (qw(FileClass FilePath)) {
|
|
if ( !$Param{$Needed} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $Needed!",
|
|
);
|
|
return;
|
|
}
|
|
}
|
|
|
|
my $SysConfigObject = $Kernel::OM->Get('Kernel::System::SysConfig');
|
|
|
|
my %OTRS5Config;
|
|
delete $INC{ $Param{FilePath} };
|
|
$Kernel::OM->Get('Kernel::System::Main')->Require( $Param{FileClass} );
|
|
$Param{FileClass}->Load( \%OTRS5Config );
|
|
|
|
my $OTRS5ConfigFileContentList = $Kernel::OM->Get('Kernel::System::Main')->FileRead(
|
|
Location => $Param{FilePath},
|
|
Result => 'ARRAY',
|
|
);
|
|
|
|
my @DisabledOTRS5Config;
|
|
for my $Line ( @{$OTRS5ConfigFileContentList} ) {
|
|
|
|
# Check if the line starts with a delete.
|
|
if ( $Line =~ m{ \A delete[ ]\$Self->\{(.+)\};}xms ) {
|
|
my $DisabledSettingString = $1;
|
|
$DisabledSettingString =~ s{['"]}{}xmsg;
|
|
$DisabledSettingString =~ s{\}->\{}{###}xmsg;
|
|
push @DisabledOTRS5Config, $DisabledSettingString;
|
|
}
|
|
}
|
|
|
|
# get all OTRS 6 default settings
|
|
my @DefaultSettings = $SysConfigObject->ConfigurationList();
|
|
|
|
# search for settings with ### in the name
|
|
# my @SearchResult = grep /###/, sort values %DefaultSettings;
|
|
my @SearchResult = grep { $_->{Name} =~ m{###} } @DefaultSettings;
|
|
|
|
# find all the setting which have sublevels and store them in a hash for OTRS 6
|
|
my %SettingsWithSubLevelsOTRS6;
|
|
for my $Setting (@SearchResult) {
|
|
|
|
my @SettingNameParts = split /###/, $Setting->{Name};
|
|
|
|
my $FirstLevelKey = shift @SettingNameParts;
|
|
my $LastLevelKey = pop @SettingNameParts;
|
|
|
|
if (
|
|
@SettingNameParts
|
|
|
|
# Skip any setting with more than one sub-levels in hash key (unsupported in OTRS 5).
|
|
&& !defined $SettingsWithSubLevelsOTRS6{$FirstLevelKey}->{ $SettingNameParts[0] }
|
|
)
|
|
{
|
|
$SettingsWithSubLevelsOTRS6{$FirstLevelKey}->{ $SettingNameParts[0] }->{$LastLevelKey} = 1;
|
|
}
|
|
else {
|
|
$SettingsWithSubLevelsOTRS6{$FirstLevelKey}->{$LastLevelKey} = 1;
|
|
}
|
|
}
|
|
|
|
# get the needed ArticleTypeMapping from a YML file (needed for Postmaster filter settings later)
|
|
my $TaskConfig = $Self->GetTaskConfig( Module => 'MigrateArticleData' );
|
|
my %ArticleTypeMapping = %{ $TaskConfig->{ArticleTypeMapping} };
|
|
|
|
# build a lookup hash of all given package settings
|
|
my %PackageSettingLookup;
|
|
if ( IsArrayRefWithData( $Param{PackageSettings} ) ) {
|
|
%PackageSettingLookup = map { $_ => 1 } @{ $Param{PackageSettings} };
|
|
}
|
|
|
|
# to store settings which do not exist in OTRS 6
|
|
my @MissingSettings;
|
|
|
|
# to store unsuccessfull settings which could not be migrated
|
|
my @UnsuccessfullSettings;
|
|
|
|
# Add an additional mapping for 2-Level settings, which have a renamed first part.
|
|
if ( $Param{PackageLookupNewConfigName} ) {
|
|
|
|
my %AdditionalMapping;
|
|
for my $OldName ( sort keys %{ $Param{PackageLookupNewConfigName} } ) {
|
|
my $NewName = $Param{PackageLookupNewConfigName}->{$OldName};
|
|
|
|
$OldName =~ s{#.*\z}{}ms;
|
|
$NewName =~ s{#.*\z}{}ms;
|
|
$AdditionalMapping{$OldName} = $NewName;
|
|
}
|
|
|
|
%{ $Param{PackageLookupNewConfigName} } = ( %{ $Param{PackageLookupNewConfigName} }, %AdditionalMapping );
|
|
}
|
|
|
|
SETTINGNAME:
|
|
for my $SettingName ( sort keys %OTRS5Config ) {
|
|
|
|
# skip loader common settings
|
|
next SETTINGNAME if $SettingName eq 'Loader::Agent::CommonCSS';
|
|
next SETTINGNAME if $SettingName eq 'Loader::Agent::CommonJS';
|
|
next SETTINGNAME if $SettingName eq 'Loader::Customer::CommonCSS';
|
|
next SETTINGNAME if $SettingName eq 'Loader::Customer::CommonJS';
|
|
|
|
# skip no longer existing sysconfig settings
|
|
next SETTINGNAME if $SettingName eq 'CustomerPreferencesView';
|
|
next SETTINGNAME if $SettingName eq 'DisableMSIFrameSecurityRestricted';
|
|
next SETTINGNAME if $SettingName eq 'Frontend::AnimationEnabled';
|
|
next SETTINGNAME if $SettingName eq 'LogModule::SysLog::LogSock';
|
|
next SETTINGNAME if $SettingName eq 'PreferencesView';
|
|
next SETTINGNAME if $SettingName eq 'Ticket::Frontend::ComposeExcludeCcRecipients';
|
|
next SETTINGNAME if $SettingName eq 'TimeZoneUser';
|
|
next SETTINGNAME if $SettingName eq 'TimeZoneUserBrowserAutoOffset';
|
|
next SETTINGNAME if $SettingName eq 'Ticket::StorageModule';
|
|
next SETTINGNAME if $SettingName eq 'Ticket::StorageModule::CheckAllBackends';
|
|
next SETTINGNAME if $SettingName eq 'ArticleDir';
|
|
|
|
my $CheckSubLevels;
|
|
if ( $SettingsWithSubLevelsOTRS6{$SettingName} ) {
|
|
$CheckSubLevels = 1;
|
|
}
|
|
elsif (
|
|
$Param{PackageLookupNewConfigName}
|
|
&& $Param{PackageLookupNewConfigName}->{$SettingName}
|
|
&& $SettingsWithSubLevelsOTRS6{ $Param{PackageLookupNewConfigName}->{$SettingName} }
|
|
)
|
|
{
|
|
$CheckSubLevels = 1;
|
|
}
|
|
|
|
# check if this OTRS5 setting has subhashes in the name
|
|
if ($CheckSubLevels) {
|
|
|
|
SETTINGKEYFIRSTLEVEL:
|
|
for my $SettingKeyFirstLevel ( sort keys %{ $OTRS5Config{$SettingName} } ) {
|
|
|
|
# there is a second level
|
|
# example: Ticket::Frontend::AgentTicketZoom###Widgets###0100-TicketInformation
|
|
if (
|
|
$SettingsWithSubLevelsOTRS6{$SettingName}->{$SettingKeyFirstLevel}
|
|
&& IsHashRefWithData( $SettingsWithSubLevelsOTRS6{$SettingName}->{$SettingKeyFirstLevel} )
|
|
&& IsHashRefWithData( $OTRS5Config{$SettingName}->{$SettingKeyFirstLevel} )
|
|
)
|
|
{
|
|
|
|
SETTINGKEYSECONDLEVEL:
|
|
for my $SettingKeySecondLevel (
|
|
sort keys %{ $OTRS5Config{$SettingName}->{$SettingKeyFirstLevel} }
|
|
)
|
|
{
|
|
|
|
# get the effective value from the OTRS 5 config
|
|
my $OTRS5EffectiveValue
|
|
= $OTRS5Config{$SettingName}->{$SettingKeyFirstLevel}->{$SettingKeySecondLevel};
|
|
|
|
# build the new setting key
|
|
my $NewSettingKey
|
|
= $SettingName . '###' . $SettingKeyFirstLevel . '###' . $SettingKeySecondLevel;
|
|
|
|
# check and convert config name if it has been renamed in OTRS 6
|
|
# otherwise it will use the given old name
|
|
$NewSettingKey = $Self->_LookupNewConfigName(
|
|
OldName => $NewSettingKey,
|
|
PackageLookupNewConfigName => $Param{PackageLookupNewConfigName},
|
|
);
|
|
|
|
# skip settings which are not in the given package settings
|
|
if ( %PackageSettingLookup && !$PackageSettingLookup{$NewSettingKey} ) {
|
|
next SETTINGKEYSECONDLEVEL;
|
|
}
|
|
|
|
# try to get the default setting from OTRS 6 for the new setting name
|
|
my %OTRS6Setting = $SysConfigObject->SettingGet(
|
|
Name => $NewSettingKey,
|
|
NoLog => 1,
|
|
);
|
|
|
|
# skip settings which already have been modified in the meantime
|
|
next SETTINGKEYSECONDLEVEL if $OTRS6Setting{ModifiedID};
|
|
|
|
# skip this setting if it is a readonly setting
|
|
next SETTINGKEYSECONDLEVEL if $OTRS6Setting{IsReadonly};
|
|
|
|
# log if there is a setting that can not be found in OTRS 6 (might come from packages)
|
|
if ( !%OTRS6Setting ) {
|
|
push @MissingSettings, $NewSettingKey;
|
|
next SETTINGKEYSECONDLEVEL;
|
|
}
|
|
|
|
# check if the setting value structure from OTRS 5 is still valid on OTRS6
|
|
my %Result = $SysConfigObject->SettingEffectiveValueCheck(
|
|
EffectiveValue => $OTRS5EffectiveValue,
|
|
XMLContentParsed => $OTRS6Setting{XMLContentParsed},
|
|
NoValidation => 1,
|
|
UserID => 1,
|
|
);
|
|
|
|
if ( !$Result{Success} ) {
|
|
push @UnsuccessfullSettings, $NewSettingKey;
|
|
next SETTINGKEYSECONDLEVEL;
|
|
}
|
|
|
|
# update the setting.
|
|
%Result = $Self->_SettingUpdate(
|
|
Name => $NewSettingKey,
|
|
IsValid => 1,
|
|
EffectiveValue => $OTRS5EffectiveValue,
|
|
);
|
|
|
|
if ( !$Result{Success} ) {
|
|
push @UnsuccessfullSettings, $NewSettingKey;
|
|
next SETTINGKEYSECONDLEVEL;
|
|
}
|
|
}
|
|
}
|
|
|
|
# there is only one level
|
|
# example: Ticket::Frontend::AgentTicketService###StripEmptyLines
|
|
else {
|
|
|
|
# get the effective value from the OTRS 5 config
|
|
my $OTRS5EffectiveValue = $OTRS5Config{$SettingName}->{$SettingKeyFirstLevel};
|
|
|
|
# build the new setting key
|
|
my $NewSettingKey = $SettingName . '###' . $SettingKeyFirstLevel;
|
|
|
|
# Skip not longer existing settings.
|
|
if ( $NewSettingKey eq 'Ticket::Frontend::OverviewSmall###ColumnHeader' ) {
|
|
next SETTINGKEYFIRSTLEVEL;
|
|
}
|
|
|
|
# check and convert config name if it has been renamed in OTRS 6
|
|
# otherwise it will use the given old name
|
|
$NewSettingKey = $Self->_LookupNewConfigName(
|
|
OldName => $NewSettingKey,
|
|
PackageLookupNewConfigName => $Param{PackageLookupNewConfigName},
|
|
);
|
|
|
|
# skip settings which are not in the given package settings
|
|
if ( %PackageSettingLookup && !$PackageSettingLookup{$NewSettingKey} ) {
|
|
next SETTINGKEYFIRSTLEVEL;
|
|
}
|
|
|
|
# try to get the default setting from OTRS 6 for the modified setting name
|
|
my %OTRS6Setting = $SysConfigObject->SettingGet(
|
|
Name => $NewSettingKey,
|
|
NoLog => 1,
|
|
);
|
|
|
|
# skip settings which already have been modified in the meantime
|
|
next SETTINGKEYFIRSTLEVEL if $OTRS6Setting{ModifiedID};
|
|
|
|
# skip this setting if it is a readonly setting
|
|
next SETTINGKEYFIRSTLEVEL if $OTRS6Setting{IsReadonly};
|
|
|
|
# log if there is a setting that can not be found in OTRS 6 (might come from packages)
|
|
if ( !%OTRS6Setting ) {
|
|
push @MissingSettings, $NewSettingKey;
|
|
next SETTINGKEYFIRSTLEVEL;
|
|
}
|
|
|
|
# migrate frontend module registrations
|
|
if (
|
|
$SettingName eq 'Frontend::Module'
|
|
|| $SettingName eq 'CustomerFrontend::Module'
|
|
|| $SettingName eq 'PublicFrontend::Module'
|
|
)
|
|
{
|
|
|
|
# migrate (and split) the frontend module settings
|
|
my $Result = $Self->_MigrateFrontendModuleSetting(
|
|
FrontendSettingName => $SettingName,
|
|
FrontendModuleName => $SettingKeyFirstLevel,
|
|
OTRS5EffectiveValue => $OTRS5EffectiveValue,
|
|
OTRS6Setting => \%OTRS6Setting,
|
|
);
|
|
|
|
# success
|
|
next SETTINGKEYFIRSTLEVEL if $Result;
|
|
|
|
# error
|
|
push @UnsuccessfullSettings, $NewSettingKey;
|
|
next SETTINGKEYFIRSTLEVEL;
|
|
}
|
|
|
|
# migrate preferences groups settings
|
|
if ( $SettingName eq 'PreferencesGroups' ) {
|
|
|
|
# delete no longer needed column key
|
|
delete $OTRS5EffectiveValue->{Column};
|
|
|
|
# add new PreferenceGroup key from OTRS 6
|
|
$OTRS5EffectiveValue->{PreferenceGroup} = $OTRS6Setting{EffectiveValue}->{PreferenceGroup};
|
|
}
|
|
|
|
# Migrate Postmaster settings for
|
|
# PostMaster::PreFilterModule
|
|
# PostMaster::PreCreateFilterModule
|
|
# PostMaster::PostFilterModule
|
|
# PostMaster::CheckFollowUpModule
|
|
if (
|
|
$SettingName
|
|
=~ m{ \A PostMaster::(PreFilter|PreCreateFilter|PostFilter|CheckFollowUp)Module \z }xms
|
|
)
|
|
{
|
|
|
|
# update no longer existing module.
|
|
if (
|
|
$OTRS5EffectiveValue->{Module} eq
|
|
'Kernel::System::PostMaster::Filter::FollowUpArticleTypeCheck'
|
|
)
|
|
{
|
|
$OTRS5EffectiveValue->{Module}
|
|
= 'Kernel::System::PostMaster::Filter::FollowUpArticleVisibilityCheck';
|
|
}
|
|
|
|
# Define mapping for old to new keys.
|
|
my %Old2NewKeyMapping = (
|
|
'X-OTRS-ArticleType' => 'X-OTRS-IsVisibleForCustomer',
|
|
'X-OTRS-FollowUp-ArticleType' => 'X-OTRS-FollowUp-IsVisibleForCustomer',
|
|
'ArticleType' => 'IsVisibleForCustomer',
|
|
);
|
|
|
|
OLDKEY:
|
|
for my $OldKey ( sort keys %Old2NewKeyMapping ) {
|
|
|
|
my $NewKey = $Old2NewKeyMapping{$OldKey};
|
|
|
|
# Convert subentries below Match and Set.
|
|
AREA:
|
|
for my $Area (qw(Match Set)) {
|
|
next AREA if !IsHashRefWithData( $OTRS5EffectiveValue->{$Area} );
|
|
next AREA if !$OTRS5EffectiveValue->{$Area}->{$OldKey};
|
|
|
|
# Add the new key with the converted value from the old key.
|
|
$OTRS5EffectiveValue->{$Area}->{$NewKey}
|
|
= $ArticleTypeMapping{ $OTRS5EffectiveValue->{$Area}->{$OldKey} }->{Visible};
|
|
|
|
# Delete the old key.
|
|
delete $OTRS5EffectiveValue->{$Area}->{$OldKey};
|
|
}
|
|
|
|
# Convert direct entries.
|
|
next OLDKEY if !$OTRS5EffectiveValue->{$OldKey};
|
|
|
|
# Add the new key with the converted value from the old key.
|
|
$OTRS5EffectiveValue->{$NewKey}
|
|
= $ArticleTypeMapping{ $OTRS5EffectiveValue->{$OldKey} }->{Visible};
|
|
|
|
# Delete the old key.
|
|
delete $OTRS5EffectiveValue->{$OldKey};
|
|
}
|
|
}
|
|
|
|
# check if the setting value structure from OTRS 5 is still valid on OTRS6
|
|
my %Result = $SysConfigObject->SettingEffectiveValueCheck(
|
|
EffectiveValue => $OTRS5EffectiveValue,
|
|
XMLContentParsed => $OTRS6Setting{XMLContentParsed},
|
|
NoValidation => 1,
|
|
UserID => 1,
|
|
);
|
|
|
|
if ( !$Result{Success} ) {
|
|
push @UnsuccessfullSettings, $NewSettingKey;
|
|
next SETTINGKEYFIRSTLEVEL;
|
|
}
|
|
|
|
# update the setting.
|
|
%Result = $Self->_SettingUpdate(
|
|
Name => $NewSettingKey,
|
|
IsValid => 1,
|
|
EffectiveValue => $OTRS5EffectiveValue,
|
|
);
|
|
|
|
if ( !$Result{Success} ) {
|
|
push @UnsuccessfullSettings, $NewSettingKey;
|
|
next SETTINGKEYFIRSTLEVEL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# setting has no subhashes in the name
|
|
# example: Cache::Module
|
|
else {
|
|
|
|
# skip TimeZone::Calendar settings (they are handled else where)
|
|
next SETTINGNAME if $SettingName =~ m{ \A TimeZone::Calendar[1-9] \z }xms;
|
|
|
|
# check and convert config name if it has been renamed in OTRS 6
|
|
# otherwise it will use the given old name
|
|
my $NewSettingName = $Self->_LookupNewConfigName(
|
|
OldName => $SettingName,
|
|
PackageLookupNewConfigName => $Param{PackageLookupNewConfigName},
|
|
);
|
|
|
|
# skip settings which are not in the given package settings
|
|
if ( %PackageSettingLookup && !$PackageSettingLookup{$NewSettingName} ) {
|
|
next SETTINGNAME;
|
|
}
|
|
|
|
# get the (default) setting from OTRS 6 for this setting name
|
|
my %OTRS6Setting = $SysConfigObject->SettingGet(
|
|
Name => $NewSettingName,
|
|
NoLog => 1,
|
|
);
|
|
|
|
# skip this setting if it has already been modified in the meantime
|
|
next SETTINGNAME if $OTRS6Setting{ModifiedID};
|
|
|
|
# skip this setting if it is a readonly setting
|
|
next SETTINGNAME if $OTRS6Setting{IsReadonly};
|
|
|
|
# Log if there is a setting that can not be found in OTRS 6 (might come from packages)
|
|
if ( !%OTRS6Setting ) {
|
|
push @MissingSettings, $NewSettingName;
|
|
next SETTINGNAME;
|
|
}
|
|
|
|
my $OTRS5EffectiveValue = $OTRS5Config{$SettingName};
|
|
|
|
# the ticket number generator random is dropped from OTRS 6, enforce that DateChecksum is set instead
|
|
if (
|
|
$NewSettingName eq 'Ticket::NumberGenerator'
|
|
&& $OTRS5EffectiveValue eq 'Kernel::System::Ticket::Number::Random'
|
|
)
|
|
{
|
|
$OTRS5EffectiveValue = 'Kernel::System::Ticket::Number::DateChecksum';
|
|
}
|
|
|
|
# check if the setting value structure from OTRS 5 is still valid on OTRS6
|
|
my %Result = $SysConfigObject->SettingEffectiveValueCheck(
|
|
EffectiveValue => $OTRS5EffectiveValue,
|
|
XMLContentParsed => $OTRS6Setting{XMLContentParsed},
|
|
NoValidation => 1,
|
|
UserID => 1,
|
|
);
|
|
|
|
if ( !$Result{Success} ) {
|
|
|
|
push @UnsuccessfullSettings, $NewSettingName;
|
|
next SETTINGNAME;
|
|
}
|
|
|
|
# update the setting.
|
|
%Result = $Self->_SettingUpdate(
|
|
Name => $NewSettingName,
|
|
IsValid => 1,
|
|
EffectiveValue => $OTRS5EffectiveValue,
|
|
);
|
|
|
|
if ( !$Result{Success} ) {
|
|
push @UnsuccessfullSettings, $NewSettingName;
|
|
next SETTINGNAME;
|
|
}
|
|
}
|
|
}
|
|
|
|
my $DisabledSettingsCount = 0;
|
|
|
|
# Set all settings which are disabled in OTRS 5 to disabled.
|
|
DISABLEDSETTINGNAME:
|
|
for my $DisabledSettingKey (@DisabledOTRS5Config) {
|
|
|
|
# Check and convert config name if it has been renamed in OTRS 6
|
|
# otherwise it will use the given old name.
|
|
my $NewSettingKey = $Self->_LookupNewConfigName(
|
|
OldName => $DisabledSettingKey,
|
|
PackageLookupNewConfigName => $Param{PackageLookupNewConfigName},
|
|
);
|
|
|
|
# Skip settings which are not in the given package settings.
|
|
if ( %PackageSettingLookup && !$PackageSettingLookup{$NewSettingKey} ) {
|
|
next DISABLEDSETTINGNAME;
|
|
}
|
|
|
|
# Try to get the default setting from OTRS 6 for the modified setting name.
|
|
my %OTRS6Setting = $SysConfigObject->SettingGet(
|
|
Name => $NewSettingKey,
|
|
NoLog => 1,
|
|
);
|
|
|
|
# Skip settings which already have been modified in the meantime.
|
|
next DISABLEDSETTINGNAME if $OTRS6Setting{ModifiedID};
|
|
|
|
# Skip this setting if it is a readonly setting.
|
|
next DISABLEDSETTINGNAME if $OTRS6Setting{IsReadonly};
|
|
|
|
# Skip this setting if it is a required setting.
|
|
next DISABLEDSETTINGNAME if $OTRS6Setting{IsRequired};
|
|
|
|
# Log if there is a setting that can not be found in OTRS 6 (might come from packages).
|
|
if ( !%OTRS6Setting ) {
|
|
push @MissingSettings, $NewSettingKey;
|
|
next DISABLEDSETTINGNAME;
|
|
}
|
|
|
|
# Disable the setting.
|
|
my %Result = $Self->_SettingUpdate(
|
|
Name => $NewSettingKey,
|
|
IsValid => 0,
|
|
);
|
|
|
|
if ( !$Result{Success} ) {
|
|
push @UnsuccessfullSettings, $NewSettingKey;
|
|
next DISABLEDSETTINGNAME;
|
|
}
|
|
|
|
$DisabledSettingsCount++;
|
|
}
|
|
|
|
# do not print the following status output if not wanted
|
|
return 1 if $Param{NoOutput};
|
|
|
|
my $AllSettingsCount = scalar keys %OTRS5Config;
|
|
|
|
print "\n";
|
|
print " - AllSettingsCount: " . $AllSettingsCount . "\n";
|
|
print " - DisabledCount: " . $DisabledSettingsCount . "\n";
|
|
print " - MissingCount: " . scalar @MissingSettings . "\n";
|
|
print " - UnsuccessfullCount: " . scalar @UnsuccessfullSettings . "\n\n";
|
|
|
|
if (@MissingSettings) {
|
|
print "\nMissing Settings: \n";
|
|
for my $Setting (@MissingSettings) {
|
|
print $Setting . "\n";
|
|
}
|
|
}
|
|
|
|
if (@UnsuccessfullSettings) {
|
|
print "\nUnsuccessfull Settings: \n";
|
|
for my $Setting (@UnsuccessfullSettings) {
|
|
print $Setting . "\n";
|
|
}
|
|
}
|
|
|
|
if ( $Param{ReturnMigratedSettingsCounts} ) {
|
|
return {
|
|
AllSettingsCount => $AllSettingsCount,
|
|
DisabledSettingsCount => $DisabledSettingsCount,
|
|
MissingSettings => \@MissingSettings,
|
|
UnsuccessfullSettings => \@UnsuccessfullSettings,
|
|
};
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
=head2 NavigationLookupGet()
|
|
|
|
Get a list of all old Sub-Groups and the corresponding new navigation.
|
|
|
|
my %NavigationLookup = $SysConfigMigrationObject->NavigationLookupGet();
|
|
|
|
Returns:
|
|
|
|
%NavigationLookup = (
|
|
'Old::Subgroup' => 'New::Navigation',
|
|
# ...
|
|
);
|
|
|
|
=cut
|
|
|
|
sub NavigationLookupGet {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
return (
|
|
'CloudService::Admin::ModuleRegistration' => 'CloudService::Admin::ModuleRegistration',
|
|
'ConfigLog' => 'ConfigLog',
|
|
'ConfigSwitch' => 'ConfigSwitch',
|
|
'Core' => 'Core',
|
|
'Core::AppointmentCalendar::Event' => 'Core::Event::AppointmentCalendar',
|
|
'Core::Cache' => 'Core::Cache',
|
|
'Core::CustomerCompany' => 'Core::CustomerCompany',
|
|
'Core::CustomerUser' => 'Core::CustomerUser',
|
|
'Core::Daemon::ModuleRegistration' => 'Daemon::ModuleRegistration',
|
|
'Core::DynamicField' => 'Core::DynamicFields',
|
|
'Core::Fetchmail' => 'Core::Email',
|
|
'Core::FulltextSearch' => 'Core::Ticket::FulltextSearch',
|
|
'Core::LinkObject' => 'Core::LinkObject',
|
|
'Core::Log' => 'Core::Log',
|
|
'Core::MIME-Viewer' => 'Frontend::Agent::MIMEViewer',
|
|
'Core::MirrorDB' => 'Core::DB::Mirror',
|
|
'Core::OTRSBusiness' => 'Core::OTRSBusiness',
|
|
'Core::Package' => 'Core::Package',
|
|
'Core::PDF' => 'Core::PDF',
|
|
'Core::PerformanceLog' => 'Core::PerformanceLog',
|
|
'Core::PostMaster' => 'Core::Email::PostMaster',
|
|
'Core::Queue' => 'Core::Queue',
|
|
'Core::ReferenceData' => 'Core::ReferenceData',
|
|
'Core::Sendmail' => 'Core::Email',
|
|
'Core::Session' => 'Core::Session',
|
|
'Core::SOAP' => 'Core::SOAP',
|
|
'Core::Stats' => 'Core::Stats',
|
|
'Core::Ticket' => 'Core::Ticket',
|
|
'Core::TicketACL' => 'Core::Ticket::ACL',
|
|
'Core::TicketBulkAction' => 'Frontend::Agent::View::TicketBulk',
|
|
'Core::TicketDynamicFieldDefault' => 'Core::Ticket::DynamicFieldDefault',
|
|
'Core::TicketWatcher' => 'Core::Ticket',
|
|
'Core::Time' => 'Core::Time',
|
|
'Core::Time::Calendar1' => 'Core::Time::Calendar1',
|
|
'Core::Time::Calendar2' => 'Core::Time::Calendar2',
|
|
'Core::Time::Calendar3' => 'Core::Time::Calendar3',
|
|
'Core::Time::Calendar4' => 'Core::Time::Calendar4',
|
|
'Core::Time::Calendar5' => 'Core::Time::Calendar5',
|
|
'Core::Time::Calendar6' => 'Core::Time::Calendar6',
|
|
'Core::Time::Calendar7' => 'Core::Time::Calendar7',
|
|
'Core::Time::Calendar8' => 'Core::Time::Calendar8',
|
|
'Core::Time::Calendar9' => 'Core::Time::Calendar9',
|
|
'Core::Transition' => 'Core::ProcessManagement',
|
|
'Core::Web' => 'Frontend::Base',
|
|
'Core::WebUserAgent' => 'Core::WebUserAgent',
|
|
'Crypt::PGP' => 'Core::Crypt::PGP',
|
|
'Crypt::SMIME' => 'Core::Crypt::SMIME',
|
|
'CustomerInformationCenter' => 'Frontend::Agent::View::CustomerInformationCenter',
|
|
'Daemon::SchedulerCronTaskManager::Task' => 'Daemon::SchedulerCronTaskManager::Task',
|
|
'Daemon::SchedulerGenericAgentTaskManager' => 'Daemon::SchedulerGenericAgentTaskManager',
|
|
'Daemon::SchedulerGenericInterfaceTaskManager' => 'Daemon::SchedulerGenericInterfaceTaskManager',
|
|
'Daemon::SchedulerTaskWorker' => 'Daemon::SchedulerTaskWorker',
|
|
'DynamicFields::Driver::Registration' => 'Core::DynamicFields::DriverRegistration',
|
|
'DynamicFields::ObjectType::Registration' => 'Core::DynamicFields::ObjectTypeRegistration',
|
|
|
|
# 'Frontend::Admin' => 'Frontend::Admin',
|
|
'Frontend::Admin::AdminCustomerCompany' => 'Frontend::Admin::View::CustomerCompany',
|
|
'Frontend::Admin::AdminCustomerUser' => 'Frontend::Admin::View::CustomerUser',
|
|
'Frontend::Admin::AdminNotificationEvent' => 'Frontend::Admin::View::NotificationEvent',
|
|
'Frontend::Admin::AdminSelectBox' => 'Frontend::Admin::View::SelectBox',
|
|
|
|
# 'Frontend::Admin::ModuleRegistration' => 'Frontend::Admin::ModuleRegistration',
|
|
'Frontend::Admin::SearchRouter' => 'Frontend::Admin::ModuleRegistration::MainMenu::Search',
|
|
'Frontend::Agent' => 'Frontend::Agent',
|
|
'Frontend::Agent::Auth::TwoFactor' => 'Core::Auth::Agent::TwoFactor',
|
|
'Frontend::Agent::Dashboard' => 'Frontend::Agent::View::Dashboard',
|
|
'Frontend::Agent::Dashboard::EventsTicketCalendar' => 'Frontend::Agent::View::Dashboard::EventsTicketCalendar',
|
|
'Frontend::Agent::Dashboard::TicketFilters' => 'Frontend::Agent::View::Dashboard::TicketFilters',
|
|
'Frontend::Agent::LinkObject' => 'Frontend::Agent::LinkObject',
|
|
'Frontend::Agent::ModuleMetaHead' => 'Frontend::Agent',
|
|
'Frontend::Agent::ModuleNotify' => 'Frontend::Agent::FrontendNotification',
|
|
'Frontend::Agent::NavBarModule' => 'Frontend::Agent::ModuleRegistration',
|
|
'Frontend::Agent::Preferences' => 'Frontend::Agent::View::Preferences',
|
|
'Frontend::Agent::SearchRouter' => 'Frontend::Agent::ModuleRegistration::MainMenu::Search',
|
|
'Frontend::Agent::Stats' => 'Frontend::Agent::Stats',
|
|
'Frontend::Agent::Ticket::ArticleAttachmentModule' => 'Frontend::Agent::View::TicketZoom',
|
|
'Frontend::Agent::Ticket::ArticleComposeModule' => 'Frontend::Agent::ArticleComposeModule',
|
|
'Frontend::Agent::Ticket::ArticleViewModule' => 'Frontend::Agent::View::TicketZoom',
|
|
'Frontend::Agent::Ticket::ArticleViewModulePre' => 'Frontend::Agent::View::TicketZoom',
|
|
'Frontend::Agent::Ticket::MenuModule' => 'Frontend::Agent::View::TicketZoom::MenuModule',
|
|
'Frontend::Agent::Ticket::MenuModulePre' => 'Frontend::Agent::TicketOverview::MenuModule',
|
|
'Frontend::Agent::Ticket::OverviewMenuModule' => 'Frontend::Agent::TicketOverview::MenuModule',
|
|
'Frontend::Agent::Ticket::ViewBounce' => 'Frontend::Agent::View::TicketBounce',
|
|
'Frontend::Agent::Ticket::ViewBulk' => 'Frontend::Agent::View::TicketBulk',
|
|
'Frontend::Agent::Ticket::ViewClose' => 'Frontend::Agent::View::TicketClose',
|
|
'Frontend::Agent::Ticket::ViewCompose' => 'Frontend::Agent::View::TicketCompose',
|
|
'Frontend::Agent::Ticket::ViewCustomer' => 'Frontend::Agent::View::TicketCustomer',
|
|
'Frontend::Agent::Ticket::ViewEmailNew' => 'Frontend::Agent::View::TicketEmailNew',
|
|
'Frontend::Agent::Ticket::ViewEmailOutbound' => 'Frontend::Agent::View::TicketEmailOutbound',
|
|
'Frontend::Agent::Ticket::ViewEscalation' => 'Frontend::Agent::View::TicketEscalation',
|
|
'Frontend::Agent::Ticket::ViewForward' => 'Frontend::Agent::View::TicketForward',
|
|
'Frontend::Agent::Ticket::ViewFreeText' => 'Frontend::Agent::View::TicketFreeText',
|
|
'Frontend::Agent::Ticket::ViewHistory' => 'Frontend::Agent::View::TicketHistory',
|
|
'Frontend::Agent::Ticket::ViewLocked' => 'Frontend::Agent::View::TicketLocked',
|
|
'Frontend::Agent::Ticket::ViewMerge' => 'Frontend::Agent::View::TicketMerge',
|
|
'Frontend::Agent::Ticket::ViewMove' => 'Frontend::Agent::View::TicketMove',
|
|
'Frontend::Agent::Ticket::ViewNote' => 'Frontend::Agent::View::TicketNote',
|
|
'Frontend::Agent::Ticket::ViewOwner' => 'Frontend::Agent::View::TicketOwner',
|
|
'Frontend::Agent::Ticket::ViewPending' => 'Frontend::Agent::View::TicketPending',
|
|
'Frontend::Agent::Ticket::ViewPhoneInbound' => 'Frontend::Agent::View::TicketPhoneInbound',
|
|
'Frontend::Agent::Ticket::ViewPhoneNew' => 'Frontend::Agent::View::TicketPhoneNew',
|
|
'Frontend::Agent::Ticket::ViewPhoneOutbound' => 'Frontend::Agent::View::TicketPhoneOutbound',
|
|
'Frontend::Agent::Ticket::ViewPrint' => 'Frontend::Agent::View::TicketPrint',
|
|
'Frontend::Agent::Ticket::ViewPriority' => 'Frontend::Agent::View::TicketPriority',
|
|
'Frontend::Agent::Ticket::ViewProcess' => 'Frontend::Agent::View::TicketProcess',
|
|
'Frontend::Agent::Ticket::ViewQueue' => 'Frontend::Agent::View::TicketQueue',
|
|
'Frontend::Agent::Ticket::ViewResponsible' => 'Frontend::Agent::View::TicketResponsible',
|
|
'Frontend::Agent::Ticket::ViewSearch' => 'Frontend::Agent::View::TicketSearch',
|
|
'Frontend::Agent::Ticket::ViewService' => 'Frontend::Agent::View::TicketService',
|
|
'Frontend::Agent::Ticket::ViewStatus' => 'Frontend::Agent::View::TicketStatus',
|
|
'Frontend::Agent::Ticket::ViewWatch' => 'Frontend::Agent::View::TicketWatch',
|
|
'Frontend::Agent::Ticket::ViewZoom' => 'Frontend::Agent::View::TicketZoom',
|
|
'Frontend::Agent::TicketOverview' => 'Frontend::Agent::TicketOverview',
|
|
'Frontend::Agent::ToolBarModule' => 'Frontend::Agent::ToolBar',
|
|
'Frontend::Agent::ViewCustomerUserSearch' => 'Frontend::Agent::View::CustomerUserAddressBook',
|
|
'Frontend::Agent::CustomerInformationCenter' => 'Frontend::Agent::View::CustomerInformationCenter',
|
|
'Frontend::Agent::Stats' => 'Frontend::Agent::View::Stats',
|
|
'Frontend::Customer' => 'Frontend::Customer',
|
|
'Frontend::Customer::Auth' => 'Core::Auth::Customer',
|
|
'Frontend::Customer::Auth::TwoFactor' => 'Core::Auth::Customer::TwoFactor',
|
|
'Frontend::Customer::ModuleMetaHead' => 'Frontend::Customer',
|
|
'Frontend::Customer::ModuleNotify' => 'Frontend::Customer::FrontendNotification',
|
|
'Frontend::Customer::ModuleRegistration' => 'Frontend::Customer::ModuleRegistration',
|
|
'Frontend::Customer::NavBarModule' => 'Frontend::Customer::ModuleRegistration',
|
|
'Frontend::Customer::Preferences' => 'Frontend::Customer::View::Preferences',
|
|
'Frontend::Customer::Ticket::ViewNew' => 'Frontend::Customer::View::TicketMessage',
|
|
'Frontend::Customer::Ticket::ViewPrint' => 'Frontend::Customer::View::TicketPrint',
|
|
'Frontend::Customer::Ticket::ViewSearch' => 'Frontend::Customer::View::TicketSearch',
|
|
'Frontend::Customer::Ticket::ViewZoom' => 'Frontend::Customer::View::TicketZoom',
|
|
'Frontend::Customer::TicketOverview' => 'Frontend::Customer::View::TicketOverview',
|
|
'Frontend::Public' => 'Frontend::Public',
|
|
'Frontend::Public::ModuleRegistration' => 'Frontend::Public::ModuleRegistration',
|
|
'Frontend::Queue::Preferences' => 'Core::Queue',
|
|
'Frontend::Service::Preferences' => 'Core::Service',
|
|
'Frontend::SLA::Preferences' => 'Core::SLA',
|
|
'GenericInterface::Invoker::ModuleRegistration' => 'GenericInterface::Invoker::ModuleRegistration',
|
|
'GenericInterface::Mapping::ModuleRegistration' => 'GenericInterface::Mapping::ModuleRegistration',
|
|
'GenericInterface::Operation::ModuleRegistration' => 'GenericInterface::Operation::ModuleRegistration',
|
|
'GenericInterface::Operation::ResponseLoggingMaxSize' => 'GenericInterface::Operation::ResponseLoggingMaxSize',
|
|
'GenericInterface::Operation::TicketCreate' => 'GenericInterface::Operation::TicketCreate',
|
|
'GenericInterface::Operation::TicketSearch' => 'GenericInterface::Operation::TicketSearch',
|
|
'GenericInterface::Operation::TicketUpdate' => 'GenericInterface::Operation::TicketUpdate',
|
|
'GenericInterface::Transport::ModuleRegistration' => 'GenericInterface::Transport::ModuleRegistration',
|
|
'GenericInterface::Webservice' => 'GenericInterface::Webservice',
|
|
'SystemMaintenance' => 'Core::SystemMaintenance',
|
|
|
|
# Packages
|
|
'OutputFilter' => 'Frontend::Base::OutputFilter',
|
|
'Frontend::Customer::ModuleMetaHead' => 'Frontend::Customer',
|
|
'Frontend::Public::ModuleMetaHead' => 'Frontend::Public',
|
|
|
|
# OTRSBusiness
|
|
'Core::NotificationEvent' => 'Frontend::Agent::View::NotificationView',
|
|
'Core::NotificationView' => 'Frontend::Agent::View::NotificationView',
|
|
'Core::NotificationView::BulkAction' => 'Frontend::Agent::View::NotificationView',
|
|
'Frontend::Agent::NotificationView' => 'Frontend::Agent::View::NotificationView',
|
|
'Frontend' => 'Frontend::Base',
|
|
'Frontend::Admin::AdminContactWithData' => 'Frontend::Admin::View::ContactWithData',
|
|
);
|
|
}
|
|
|
|
=head1 PRIVATE INTERFACE
|
|
|
|
=head2 _LookupNewConfigName()
|
|
|
|
Helper function to lookup new config names for configuration settings
|
|
where the name has been changed from OTRS 5 to OTRS 6.
|
|
|
|
my $NewName = $SysConfigMigrationObject->_LookupNewConfigName(
|
|
OldName => 'CustomerCompany::EventModulePost###100-UpdateCustomerUsers',
|
|
);
|
|
|
|
Returns:
|
|
|
|
True on success or false on error.
|
|
|
|
=cut
|
|
|
|
sub _LookupNewConfigName {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
# check needed stuff
|
|
if ( !$Param{OldName} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need OldName!",
|
|
);
|
|
return;
|
|
}
|
|
|
|
# mapping table: old name -> new name
|
|
my %Old2NewName = (
|
|
'CustomerCompany::EventModulePost###100-UpdateCustomerUsers' =>
|
|
'CustomerCompany::EventModulePost###2000-UpdateCustomerUsers',
|
|
|
|
'CustomerCompany::EventModulePost###110-UpdateTickets' =>
|
|
'CustomerCompany::EventModulePost###2300-UpdateTickets',
|
|
|
|
'CustomerCompany::EventModulePost###1000-GenericInterface' =>
|
|
'CustomerCompany::EventModulePost###9900-GenericInterface',
|
|
|
|
'CustomerUser::EventModulePost###100-UpdateDynamicFieldObjectName' =>
|
|
'CustomerUser::EventModulePost###2000-UpdateDynamicFieldObjectName',
|
|
|
|
'CustomerUser::EventModulePost###100-UpdateSearchProfiles' =>
|
|
'CustomerUser::EventModulePost###2100-UpdateSearchProfiles',
|
|
|
|
'CustomerUser::EventModulePost###100-UpdateServiceMembership' =>
|
|
'CustomerUser::EventModulePost###2200-UpdateServiceMembership',
|
|
|
|
'CustomerUser::EventModulePost###1000-GenericInterface' =>
|
|
'CustomerUser::EventModulePost###9900-GenericInterface',
|
|
|
|
'CustomerUser::EventModulePost###120-UpdateTickets' =>
|
|
'CustomerUser::EventModulePost###2300-UpdateTickets',
|
|
|
|
'DynamicField::EventModulePost###1000-GenericInterface' =>
|
|
'DynamicField::EventModulePost###9900-GenericInterface',
|
|
|
|
'Frontend::NotifyModule###5-Ticket::TicketEscalation' =>
|
|
'Frontend::NotifyModule###5000-Ticket::TicketEscalation',
|
|
|
|
'Frontend::NotifyModule###100-CloudServicesDisabled' =>
|
|
'Frontend::NotifyModule###1000-CloudServicesDisabled',
|
|
|
|
'Frontend::NotifyModule###100-OTRSBusiness' =>
|
|
'Frontend::NotifyModule###1100-OTRSBusiness',
|
|
|
|
'Frontend::NotifyModule###200-UID-Check' =>
|
|
'Frontend::NotifyModule###2000-UID-Check',
|
|
|
|
'Frontend::NotifyModule###250-AgentSessionLimit' =>
|
|
'Frontend::NotifyModule###2500-AgentSessionLimit',
|
|
|
|
'Frontend::NotifyModule###300-ShowAgentOnline' =>
|
|
'Frontend::NotifyModule###3000-ShowAgentOnline',
|
|
|
|
'Frontend::NotifyModule###400-ShowCustomerOnline' =>
|
|
'Frontend::NotifyModule###4000-ShowCustomerOnline',
|
|
|
|
'Frontend::NotifyModule###500-OutofOffice-Check' =>
|
|
'Frontend::NotifyModule###5500-OutofOffice-Check',
|
|
|
|
'Frontend::NotifyModule###600-SystemMaintenance-Check' =>
|
|
'Frontend::NotifyModule###6000-SystemMaintenance-Check',
|
|
|
|
'Frontend::NotifyModule###700-AgentTimeZone-Check' =>
|
|
'Frontend::NotifyModule###7000-AgentTimeZone-Check',
|
|
|
|
'Frontend::NotifyModule###800-Daemon-Check' =>
|
|
'Frontend::NotifyModule###8000-Daemon-Check',
|
|
|
|
'Frontend::NotifyModule###900-Generic' =>
|
|
'Frontend::NotifyModule###9000-Generic',
|
|
|
|
'Frontend::ToolBarModule###1-Ticket::AgentTicketQueue' =>
|
|
'Frontend::ToolBarModule###110-Ticket::AgentTicketQueue',
|
|
|
|
'Frontend::ToolBarModule###2-Ticket::AgentTicketStatus' =>
|
|
'Frontend::ToolBarModule###120-Ticket::AgentTicketStatus',
|
|
|
|
'Frontend::ToolBarModule###3-Ticket::AgentTicketEscalation' =>
|
|
'Frontend::ToolBarModule###130-Ticket::AgentTicketEscalation',
|
|
|
|
'Frontend::ToolBarModule###4-Ticket::AgentTicketPhone' =>
|
|
'Frontend::ToolBarModule###140-Ticket::AgentTicketPhone',
|
|
|
|
'Frontend::ToolBarModule###5-Ticket::AgentTicketEmail' =>
|
|
'Frontend::ToolBarModule###150-Ticket::AgentTicketEmail',
|
|
|
|
'Frontend::ToolBarModule###6-Ticket::AgentTicketProcess' =>
|
|
'Frontend::ToolBarModule###160-Ticket::AgentTicketProcess',
|
|
|
|
'Frontend::ToolBarModule###7-Ticket::TicketResponsible' =>
|
|
'Frontend::ToolBarModule###170-Ticket::TicketResponsible',
|
|
|
|
'Frontend::ToolBarModule###8-Ticket::TicketWatcher' =>
|
|
'Frontend::ToolBarModule###180-Ticket::TicketWatcher',
|
|
|
|
'Frontend::ToolBarModule###9-Ticket::TicketLocked' =>
|
|
'Frontend::ToolBarModule###190-Ticket::TicketLocked',
|
|
|
|
'Frontend::ToolBarModule###10-Ticket::AgentTicketService' =>
|
|
'Frontend::ToolBarModule###200-Ticket::AgentTicketService',
|
|
|
|
'Frontend::ToolBarModule###11-Ticket::TicketSearchProfile' =>
|
|
'Frontend::ToolBarModule###210-Ticket::TicketSearchProfile',
|
|
|
|
'Frontend::ToolBarModule###12-Ticket::TicketSearchFulltext' =>,
|
|
'Frontend::ToolBarModule###220-Ticket::TicketSearchFulltext',
|
|
|
|
'Frontend::ToolBarModule###13-CICSearchCustomerID' =>
|
|
'Frontend::ToolBarModule###230-CICSearchCustomerID',
|
|
|
|
'Frontend::ToolBarModule###14-CICSearchCustomerUser' =>
|
|
'Frontend::ToolBarModule###240-CICSearchCustomerUser',
|
|
|
|
'Package::EventModulePost###1000-GenericInterface' =>
|
|
'Package::EventModulePost###9900-GenericInterface',
|
|
|
|
'Package::EventModulePost###99-SupportDataSend' =>
|
|
'Package::EventModulePost###9000-SupportDataSend',
|
|
|
|
'Queue::EventModulePost###1000-GenericInterface' =>
|
|
'Queue::EventModulePost###9900-GenericInterface',
|
|
|
|
'Queue::EventModulePost###130-UpdateQueue' =>
|
|
'Queue::EventModulePost###2300-UpdateQueue',
|
|
|
|
'Ticket::EventModulePost###100-ArchiveRestore' =>
|
|
'Ticket::EventModulePost###2300-ArchiveRestore',
|
|
|
|
'Ticket::EventModulePost###110-AcceleratorUpdate' =>
|
|
'Ticket::EventModulePost###2600-AcceleratorUpdate',
|
|
|
|
'Ticket::EventModulePost###120-ForceOwnerResetOnMove' =>
|
|
'Ticket::EventModulePost###2700-ForceOwnerResetOnMove',
|
|
|
|
'Ticket::EventModulePost###130-ForceStateChangeOnLock' =>
|
|
'Ticket::EventModulePost###2800-ForceStateChangeOnLock',
|
|
|
|
'Ticket::EventModulePost###140-ResponsibleAutoSet' =>
|
|
'Ticket::EventModulePost###3000-ResponsibleAutoSet',
|
|
|
|
'Ticket::EventModulePost###150-TicketPendingTimeReset' =>
|
|
'Ticket::EventModulePost###3300-TicketPendingTimeReset',
|
|
|
|
'Ticket::EventModulePost###500-NotificationEvent' =>
|
|
'Ticket::EventModulePost###7000-NotificationEvent',
|
|
|
|
'Ticket::EventModulePost###900-GenericAgent' =>
|
|
'Ticket::EventModulePost###9700-GenericAgent',
|
|
|
|
'Ticket::EventModulePost###910-EscalationIndex' =>
|
|
'Ticket::EventModulePost###6000-EscalationIndex',
|
|
|
|
'Ticket::EventModulePost###920-EscalationStopEvents' =>
|
|
'Ticket::EventModulePost###4300-EscalationStopEvents',
|
|
|
|
'Ticket::EventModulePost###930-ForceUnlockOnMove' =>
|
|
'Ticket::EventModulePost###3600-ForceUnlockOnMove',
|
|
|
|
'Ticket::EventModulePost###940-TicketArticleNewMessageUpdate' =>
|
|
'Ticket::EventModulePost###4000-TicketArticleNewMessageUpdate',
|
|
|
|
'Ticket::EventModulePost###950-DynamicFieldFromCustomerUser' =>
|
|
'Ticket::EventModulePost###4100-DynamicFieldFromCustomerUser',
|
|
|
|
'Ticket::EventModulePost###998-TicketProcessTransitions' =>
|
|
'Ticket::EventModulePost###9800-TicketProcessTransitions',
|
|
|
|
'Ticket::EventModulePost###999-GenericInterface' =>
|
|
'Ticket::EventModulePost###9900-GenericInterface',
|
|
|
|
'Ticket::EventModulePost###TicketDynamicFieldDefault' =>
|
|
'Ticket::EventModulePost###9600-TicketDynamicFieldDefault',
|
|
|
|
'Ticket::Frontend::ArticleComposeModule###1-SignEmail' =>
|
|
'Ticket::Frontend::ArticleComposeModule###2-SignEmail',
|
|
|
|
'Ticket::Frontend::ArticleComposeModule###2-CryptEmail' =>
|
|
'Ticket::Frontend::ArticleComposeModule###3-CryptEmail',
|
|
|
|
'Ticket::Frontend::ArticlePreViewModule###1-SMIME' =>
|
|
'Ticket::Frontend::ArticlePreViewModule###2-SMIME',
|
|
|
|
'PostMaster::PreCreateFilterModule###000-FollowUpArticleTypeCheck' =>
|
|
'PostMaster::PreCreateFilterModule###000-FollowUpArticleVisibilityCheck',
|
|
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###From' =>
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###MIMEBase_From',
|
|
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###To' =>
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###MIMEBase_To',
|
|
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###Cc' =>
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###MIMEBase_Cc',
|
|
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###Subject' =>
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###MIMEBase_Subject',
|
|
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###Body' =>
|
|
'Ticket::Frontend::AgentTicketSearch###Defaults###MIMEBase_Body',
|
|
|
|
# Moved and renamed config setting from OTRSBusiness.xml to Framework.xml
|
|
'ChatEngine::AgentOnlineThreshold' => 'SessionAgentOnlineThreshold',
|
|
|
|
# Moved and renamed config setting from OTRSBusiness.xml to Framework.xml
|
|
'ChatEngine::CustomerOnlineThreshold' => 'SessionCustomerOnlineThreshold',
|
|
|
|
%{ $Param{PackageLookupNewConfigName} // {} },
|
|
);
|
|
|
|
# get the new name if found, otherwise use the given old name
|
|
my $NewName = $Old2NewName{ $Param{OldName} } || $Param{OldName};
|
|
|
|
return $NewName;
|
|
}
|
|
|
|
=head2 _MigrateFrontendModuleSetting()
|
|
|
|
Helper function to migrate a frontend module setting from OTRS 5 to OTRS 6.
|
|
|
|
my $NewName = $SysConfigMigrationObject->_MigrateFrontendModuleSetting(
|
|
FrontendSettingName => 'Frontend::Module',
|
|
FrontendModuleName => 'AgentTicketQueue',
|
|
OTRS5EffectiveValue => {
|
|
'Description' => 'Overview of all open Tickets.',
|
|
'Group' => [ 'users', 'admin' ],
|
|
'GroupRo' => [ 'stats' ],
|
|
'Loader' => {
|
|
'CSS' => [
|
|
'Core.AgentTicketQueue.css',
|
|
'Core.AllocationList.css'
|
|
],
|
|
'JavaScript' => [
|
|
'Core.UI.AllocationList.js',
|
|
'Core.Agent.TableFilters.js'
|
|
],
|
|
},
|
|
'NavBar' => [
|
|
{
|
|
'AccessKey' => 'o',
|
|
'Block' => '',
|
|
'Description' => 'Overview of all open Tickets. xxx xxx',
|
|
'Link' => 'Action=AgentTicketQueue',
|
|
'LinkOption' => '',
|
|
'Name' => 'Queue view',
|
|
'NavBar' => 'Ticket',
|
|
'Prio' => '100',
|
|
'Type' => ''
|
|
},
|
|
{
|
|
'AccessKey' => 't',
|
|
'Block' => 'ItemArea',
|
|
'Description' => 'xxx',
|
|
'Link' => 'Action=AgentTicketQueue',
|
|
'LinkOption' => '',
|
|
'Name' => 'Tickets',
|
|
'NavBar' => 'Ticket',
|
|
'Prio' => '200',
|
|
'Type' => 'Menu'
|
|
}
|
|
],
|
|
'NavBarName' => 'Ticket',
|
|
'Title' => 'QueueView',
|
|
},
|
|
OTRS6Setting => \%OTRS6Setting,
|
|
);
|
|
|
|
Returns:
|
|
|
|
True on success or false on error.
|
|
|
|
=cut
|
|
|
|
sub _MigrateFrontendModuleSetting {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
# check needed stuff
|
|
for my $Needed (qw(FrontendSettingName FrontendModuleName OTRS5EffectiveValue OTRS6Setting)) {
|
|
if ( !$Param{$Needed} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $Needed!",
|
|
);
|
|
return;
|
|
}
|
|
}
|
|
|
|
# get the group settings from OTRS 5 config
|
|
my @Group = @{ $Param{OTRS5EffectiveValue}->{Group} || [] };
|
|
my @GroupRo = @{ $Param{OTRS5EffectiveValue}->{GroupRo} || [] };
|
|
|
|
my $SysConfigObject = $Kernel::OM->Get('Kernel::System::SysConfig');
|
|
|
|
# ###########################################################################
|
|
# migrate the frontend module setting
|
|
# (it will contain only the registration,
|
|
# loader and navigation settings will be separate settings now)
|
|
# ###########################################################################
|
|
|
|
# set some attributes from OTRS 5
|
|
ATTRIBUTE:
|
|
for my $Attribute (qw(Description Title NavBarName)) {
|
|
next ATTRIBUTE if !$Param{OTRS5EffectiveValue}->{$Attribute};
|
|
$Param{OTRS6Setting}->{EffectiveValue}->{$Attribute} = $Param{OTRS5EffectiveValue}->{$Attribute};
|
|
}
|
|
|
|
# set group settings from OTRS 5
|
|
$Param{OTRS6Setting}->{EffectiveValue}->{Group} = \@Group;
|
|
$Param{OTRS6Setting}->{EffectiveValue}->{GroupRo} = \@GroupRo;
|
|
|
|
# check if the setting value structure from OTRS 5 is still valid on OTRS 6
|
|
my %Result = $SysConfigObject->SettingEffectiveValueCheck(
|
|
EffectiveValue => $Param{OTRS5EffectiveValue},
|
|
XMLContentParsed => $Param{OTRS6Setting}->{XMLContentParsed},
|
|
NoValidation => 1,
|
|
UserID => 1,
|
|
);
|
|
|
|
return if !$Result{Success};
|
|
|
|
# lock the setting
|
|
my $ExclusiveLockGUID = $SysConfigObject->SettingLock(
|
|
Name => $Param{OTRS6Setting}->{Name},
|
|
Force => 1,
|
|
UserID => 1,
|
|
);
|
|
|
|
# update the setting
|
|
%Result = $SysConfigObject->SettingUpdate(
|
|
Name => $Param{OTRS6Setting}->{Name},
|
|
IsValid => 1,
|
|
EffectiveValue => $Param{OTRS6Setting}->{EffectiveValue},
|
|
ExclusiveLockGUID => $ExclusiveLockGUID,
|
|
NoValidation => 1,
|
|
UserID => 1,
|
|
);
|
|
|
|
# unlock the setting again
|
|
$SysConfigObject->SettingUnlock(
|
|
Name => $Param{OTRS6Setting}->{Name},
|
|
);
|
|
|
|
return if !$Result{Success};
|
|
|
|
# ###########################################################################
|
|
# migrate the NavBarModule settings
|
|
# ###########################################################################
|
|
if ( $Param{OTRS5EffectiveValue}->{NavBarModule} ) {
|
|
|
|
my $NavBarModuleSettingName = 'Frontend::NavigationModule###' . $Param{FrontendModuleName};
|
|
|
|
# try to get the (default) setting from OTRS 6 for the NavBarModule setting
|
|
my %OTRS6NavBarModuleSetting = $SysConfigObject->SettingGet(
|
|
Name => $NavBarModuleSettingName,
|
|
NoLog => 1,
|
|
);
|
|
|
|
if (
|
|
%OTRS6NavBarModuleSetting
|
|
&& !$OTRS6NavBarModuleSetting{ModifiedID}
|
|
&& !$OTRS6NavBarModuleSetting{IsReadonly}
|
|
)
|
|
{
|
|
|
|
# set group settings from OTRS 5
|
|
$OTRS6NavBarModuleSetting{EffectiveValue}->{Group} = \@Group;
|
|
$OTRS6NavBarModuleSetting{EffectiveValue}->{GroupRo} = \@GroupRo;
|
|
|
|
# take NavBarModule settings from OTRS 5
|
|
for my $Attribute ( sort keys %{ $Param{OTRS5EffectiveValue}->{NavBarModule} } ) {
|
|
$OTRS6NavBarModuleSetting{EffectiveValue}->{$Attribute}
|
|
= $Param{OTRS5EffectiveValue}->{NavBarModule}->{$Attribute};
|
|
}
|
|
|
|
# lock the setting
|
|
my $ExclusiveLockGUID = $SysConfigObject->SettingLock(
|
|
Name => $NavBarModuleSettingName,
|
|
Force => 1,
|
|
UserID => 1,
|
|
);
|
|
|
|
# update the setting
|
|
my %Result = $SysConfigObject->SettingUpdate(
|
|
Name => $NavBarModuleSettingName,
|
|
IsValid => 1,
|
|
EffectiveValue => $OTRS6NavBarModuleSetting{EffectiveValue},
|
|
ExclusiveLockGUID => $ExclusiveLockGUID,
|
|
NoValidation => 1,
|
|
UserID => 1,
|
|
);
|
|
|
|
# unlock the setting again
|
|
$SysConfigObject->SettingUnlock(
|
|
Name => $NavBarModuleSettingName,
|
|
);
|
|
|
|
return if !$Result{Success};
|
|
}
|
|
}
|
|
|
|
# ###########################################################################
|
|
# migrate the NavBar settings
|
|
# ###########################################################################
|
|
|
|
# Skip navbar items if name is empty.
|
|
my @OTRS5NavBar = grep {
|
|
defined $_->{Name} && length $_->{Name}
|
|
} @{ $Param{OTRS5EffectiveValue}->{NavBar} || [] };
|
|
|
|
if (@OTRS5NavBar) {
|
|
|
|
# get all OTRS 6 default settings
|
|
my @DefaultSettings = $SysConfigObject->ConfigurationList();
|
|
|
|
# search for OTRS 6 NavBar settings
|
|
#
|
|
# this will find settings like:
|
|
# Frontend::Navigation###
|
|
# CustomerFrontend::Navigation###
|
|
# PublicFrontend::Navigation###
|
|
#
|
|
$Param{FrontendSettingName} =~ s{Frontend::Module}{Frontend::Navigation}gsmx;
|
|
|
|
my $Search = $Param{FrontendSettingName} . '###' . $Param{FrontendModuleName} . '###';
|
|
my @SearchResult = grep { $_->{Name} =~ m{$Search} } @DefaultSettings;
|
|
|
|
if ( scalar @SearchResult == 1 ) {
|
|
|
|
# try to get the (default) setting from OTRS 6 for the NavBar setting
|
|
my %OTRS6NavBarSetting = $SysConfigObject->SettingGet(
|
|
Name => $SearchResult[0]->{Name},
|
|
NoLog => 1,
|
|
);
|
|
|
|
return if !%OTRS6NavBarSetting;
|
|
|
|
# skip this setting if it has already been modified in the meantime
|
|
return 1 if $OTRS6NavBarSetting{ModifiedID};
|
|
|
|
# skip this setting if it is a readonly setting
|
|
return 1 if $OTRS6NavBarSetting{IsReadonly};
|
|
|
|
$OTRS6NavBarSetting{EffectiveValue} = [];
|
|
|
|
for my $OTRS5NavBarItem (@OTRS5NavBar) {
|
|
|
|
if ( !$OTRS5NavBarItem->{Group} ) {
|
|
$OTRS5NavBarItem->{Group} = \@Group;
|
|
}
|
|
if ( !$OTRS5NavBarItem->{GroupRo} ) {
|
|
$OTRS5NavBarItem->{GroupRo} = \@GroupRo;
|
|
}
|
|
|
|
push @{ $OTRS6NavBarSetting{EffectiveValue} }, $OTRS5NavBarItem;
|
|
}
|
|
|
|
# Save the updated effective value for the current setting.
|
|
my %Result = $Self->_SettingUpdate(
|
|
Name => $SearchResult[0]->{Name},
|
|
EffectiveValue => $OTRS6NavBarSetting{EffectiveValue},
|
|
IsValid => 1,
|
|
UserID => 1,
|
|
);
|
|
|
|
return if !$Result{Success};
|
|
}
|
|
}
|
|
|
|
# No NavBar entries exists in OTRS 5 config for the frontend modulel, so we disable all nav bar settings
|
|
# for this frontend navigation.
|
|
else {
|
|
|
|
# get all OTRS 6 default settings
|
|
my @DefaultSettings = $SysConfigObject->ConfigurationList();
|
|
|
|
# search for OTRS 6 NavBar settings
|
|
#
|
|
# this will find settings like:
|
|
# Frontend::Navigation###
|
|
# CustomerFrontend::Navigation###
|
|
# PublicFrontend::Navigation###
|
|
#
|
|
$Param{FrontendSettingName} =~ s{Frontend::Module}{Frontend::Navigation}gsmx;
|
|
|
|
my $Search = $Param{FrontendSettingName} . '###' . $Param{FrontendModuleName} . '###';
|
|
my @SearchResult = grep { $_->{Name} =~ m{$Search} } @DefaultSettings;
|
|
|
|
NAVBARSETTING:
|
|
for my $NavBarSetting (@SearchResult) {
|
|
my $NavBarSettingName = $NavBarSetting->{Name};
|
|
|
|
# try to get the (default) setting from OTRS 6 for the NavBar setting
|
|
my %OTRS6NavBarSetting = $SysConfigObject->SettingGet(
|
|
Name => $NavBarSettingName,
|
|
NoLog => 1,
|
|
);
|
|
|
|
next NAVBARSETTING if !%OTRS6NavBarSetting;
|
|
|
|
# skip this setting if it is already invalid
|
|
next NAVBARSETTING if !$OTRS6NavBarSetting{IsValid};
|
|
|
|
# skip this setting if it has already been modified in the meantime
|
|
next NAVBARSETTING if $OTRS6NavBarSetting{ModifiedID};
|
|
|
|
# skip this setting if it is a readonly setting
|
|
next NAVBARSETTING if $OTRS6NavBarSetting{IsReadonly};
|
|
|
|
# skip this setting if it is a required setting
|
|
next NAVBARSETTING if $OTRS6NavBarSetting{IsRequired};
|
|
|
|
# Disable the setting.
|
|
my %Result = $Self->_SettingUpdate(
|
|
Name => $NavBarSettingName,
|
|
IsValid => 0,
|
|
);
|
|
|
|
return if !$Result{Success};
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
=head2 _SettingUpdate()
|
|
|
|
This method locks provided settings(by force), updates them and unlock the setting.
|
|
|
|
my %Result = $SysConfigMigrationObject->_SettingUpdate(
|
|
Name => 'Setting::Name',
|
|
IsValid => 1, # (optional) 1 or 0, modified 0
|
|
EffectiveValue => $SettingEffectiveValue, # (optional)
|
|
);
|
|
|
|
Returns:
|
|
|
|
%Result = (
|
|
Success => 1, # or false in case of an error
|
|
Error => undef, # error message
|
|
);
|
|
|
|
=cut
|
|
|
|
sub _SettingUpdate {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
return if !$Param{Name};
|
|
|
|
my $SysConfigObject = $Kernel::OM->Get('Kernel::System::SysConfig');
|
|
|
|
# lock the setting
|
|
my $ExclusiveLockGUID = $SysConfigObject->SettingLock(
|
|
Name => $Param{Name},
|
|
Force => 1,
|
|
UserID => 1,
|
|
);
|
|
|
|
# Disable the setting.
|
|
my %Result = $SysConfigObject->SettingUpdate(
|
|
Name => $Param{Name},
|
|
IsValid => $Param{IsValid},
|
|
EffectiveValue => $Param{EffectiveValue},
|
|
ExclusiveLockGUID => $ExclusiveLockGUID,
|
|
NoValidation => 1,
|
|
UserID => 1,
|
|
);
|
|
|
|
# unlock the setting again
|
|
$SysConfigObject->SettingUnlock(
|
|
Name => $Param{Name},
|
|
);
|
|
|
|
return %Result;
|
|
}
|
|
|
|
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
|