1# --
2# Copyright (C) 2001-2020 OTRS AG, https://otrs.com/
3# --
4# This software comes with ABSOLUTELY NO WARRANTY. For details, see
5# the enclosed file COPYING for license information (GPL). If you
6# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
7# --
8
9package Kernel::Modules::AdminSystemConfigurationGroup;
10
11use strict;
12use warnings;
13
14our $ObjectManagerDisabled = 1;
15
16use Kernel::Language qw(Translatable);
17use Kernel::System::VariableCheck qw(IsArrayRefWithData);
18
19sub new {
20    my ( $Type, %Param ) = @_;
21
22    # Allocate new hash for object.
23    my $Self = {%Param};
24    bless( $Self, $Type );
25
26    return $Self;
27}
28
29sub Run {
30    my ( $Self, %Param ) = @_;
31
32    my $LayoutObject    = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
33    my $ConfigObject    = $Kernel::OM->Get('Kernel::Config');
34    my $ParamObject     = $Kernel::OM->Get('Kernel::System::Web::Request');
35    my $SysConfigObject = $Kernel::OM->Get('Kernel::System::SysConfig');
36    my $ConfigLevel     = $Kernel::OM->Get('Kernel::Config')->Get('ConfigLevel') || 0;
37
38    if ( $Self->{Subaction} eq 'Lock' ) {
39
40        # Challenge token check for write action.
41        $LayoutObject->ChallengeTokenCheck();
42
43        my $SettingName = $ParamObject->GetParam( Param => 'SettingName' ) || '';
44
45        my %Setting = $SysConfigObject->SettingGet(
46            Name            => $SettingName,
47            OverriddenInXML => 1,
48            UserID          => $Self->{UserID},
49        );
50
51        my %Result;
52
53        my %LockStatus = $SysConfigObject->SettingLockCheck(
54            DefaultID           => $Setting{DefaultID},
55            ExclusiveLockGUID   => $Setting{ExclusiveLockGUID} || '1',
56            ExclusiveLockUserID => $Self->{UserID},
57        );
58
59        my $Guid;
60        if ( !$LockStatus{Locked} ) {
61            if ( $Setting{IsValid} ) {
62                $Guid = $SysConfigObject->SettingLock(
63                    UserID    => $Self->{UserID},
64                    DefaultID => $Setting{DefaultID},
65                );
66            }
67            else {
68                # Setting can't be locked if it's disabled.
69                $Result{Error} = $Kernel::OM->Get('Kernel::Language')->Translate(
70                    "You need to enable the setting before locking!"
71                );
72                return $Self->_ReturnJSON( Response => \%Result );
73            }
74            $Setting{Locked} = $Guid ? 2 : 0;
75        }
76        elsif ( $LockStatus{Locked} == 1 ) {
77
78            # append status
79            %Setting = (
80                %Setting,
81                %LockStatus,
82            );
83
84            $Setting{Error} = '<p class="Error">'
85                . $Kernel::OM->Get('Kernel::Language')->Translate(
86                "You can't work on this setting because %s (%s) is currently working on it.",
87                $LockStatus{User}->{UserFullname},
88                $LockStatus{User}->{UserEmail},
89                );
90            $Setting{Error} .= "</p>";
91        }
92
93        $Setting{ExclusiveLockGUID} = $Guid || $Setting{ExclusiveLockGUID};
94
95        $Result{Data}->{HTMLStrg} = $SysConfigObject->SettingRender(
96            Setting => \%Setting,
97            RW      => ( $Setting{Locked} && $Setting{Locked} == 2 ) ? 1 : 0,
98            IsAjax  => 1,
99            UserID  => $Self->{UserID},
100        );
101
102        # Send only useful setting attributes to reduce ammount of data transfered in the AJAX call.
103        for my $Key (qw(IsModified IsDirty IsLocked Error ExclusiveLockGUID IsValid UserModificationActive)) {
104            $Result{Data}->{SettingData}->{$Key} = $Setting{$Key};
105        }
106
107        if ( $Result{Data}->{HTMLStrg} =~ m{BadEffectiveValue}gsmx ) {
108            $Result{Data}->{SettingData}->{Invalid} = 1;
109        }
110
111        return $Self->_ReturnJSON( Response => \%Result );
112    }
113    elsif ( $Self->{Subaction} eq 'Unlock' ) {
114
115        # Challenge token check for write action.
116        $LayoutObject->ChallengeTokenCheck();
117
118        my $SettingName = $ParamObject->GetParam( Param => 'SettingName' ) || '';
119
120        my %Result;
121
122        my %Setting = $SysConfigObject->SettingGet(
123            Name            => $SettingName,
124            OverriddenInXML => 1,
125            UserID          => $Self->{UserID},
126        );
127
128        my %LockStatus = $SysConfigObject->SettingLockCheck(
129            DefaultID           => $Setting{DefaultID},
130            ExclusiveLockGUID   => $Setting{ExclusiveLockGUID} || '1',
131            ExclusiveLockUserID => $Self->{UserID},
132        );
133
134        if ( $LockStatus{Locked} == 2 ) {
135            my $Success = $SysConfigObject->SettingUnlock(
136                DefaultID => $Setting{DefaultID},
137            );
138
139            $Setting{Locked} = $Success ? 0 : 2;
140        }
141        elsif ( $LockStatus{Locked} == 1 ) {
142
143            # append status
144            %Setting = (
145                %Setting,
146                %LockStatus,
147            );
148        }
149
150        $Result{Data}->{HTMLStrg} = $SysConfigObject->SettingRender(
151            Setting => \%Setting,
152            IsAjax  => 1,
153            RW      => ( $Setting{Locked} && $Setting{Locked} == 2 ) ? 1 : 0,
154            UserID  => $Self->{UserID},
155        );
156
157        # Send only useful setting attributes to reduce ammount of data transfered in the AJAX call.
158        for my $Key (qw(IsModified IsDirty IsLocked Error ExclusiveLockGUID IsValid UserModificationActive)) {
159            $Result{Data}->{SettingData}->{$Key} = $Setting{$Key};
160        }
161
162        if ( $Result{Data}->{HTMLStrg} =~ m{BadEffectiveValue}gsmx ) {
163            $Result{Data}->{SettingData}->{Invalid} = 1;
164        }
165
166        return $Self->_ReturnJSON( Response => \%Result );
167    }
168
169    elsif ( $Self->{Subaction} eq 'SettingReset' ) {
170
171        # Challenge token check for write action.
172        $LayoutObject->ChallengeTokenCheck();
173
174        my $ParamObject = $Kernel::OM->Get('Kernel::System::Web::Request');
175
176        my $SettingName  = $ParamObject->GetParam( Param => 'SettingName' )  || '';
177        my $ResetOptions = $ParamObject->GetParam( Param => 'ResetOptions' ) || '';
178
179        my %Result;
180
181        if ( !$SettingName ) {
182            $Result{Error} = $Kernel::OM->Get('Kernel::Language')->Translate(
183                "Missing setting name!",
184            );
185            return $Self->_ReturnJSON( Response => \%Result );
186        }
187
188        if ( !$ResetOptions ) {
189            $Result{Error} = $Kernel::OM->Get('Kernel::Language')->Translate(
190                "Missing ResetOptions!",
191            );
192            return $Self->_ReturnJSON( Response => \%Result );
193        }
194
195        my @Options = split ",", $ResetOptions;
196
197        my %Setting = $SysConfigObject->SettingGet(
198            Name => $SettingName,
199        );
200
201        if ( grep { $_ eq 'reset-globally' } @Options ) {
202
203            # Reset globally
204            my $Guid;
205
206            if ( !$Setting{ExclusiveLockGUID} ) {
207
208                # Setting is not locked yet.
209                $Guid = $SysConfigObject->SettingLock(
210                    UserID    => $Self->{UserID},
211                    DefaultID => $Setting{DefaultID},
212                );
213            }
214            elsif ( $Setting{ExclusiveLockUserID} != $Self->{UserID} ) {
215
216                # Someone else locked the setting.
217                $Result{Error} = $Kernel::OM->Get('Kernel::Language')->Translate(
218                    "Setting is locked by another user!",
219                );
220                return $Self->_ReturnJSON( Response => \%Result );
221            }
222            else {
223
224                # Already locked to this user.
225                $Guid = $Setting{ExclusiveLockGUID};
226            }
227
228            if ( !$Guid ) {
229                $Result{Error} = $Kernel::OM->Get('Kernel::Language')->Translate(
230                    "System was not able to lock the setting!",
231                );
232                return $Self->_ReturnJSON( Response => \%Result );
233            }
234
235            my $Success = $SysConfigObject->SettingReset(
236                Name              => $SettingName,
237                ExclusiveLockGUID => $Guid,
238                UserID            => $Self->{UserID},
239            );
240
241            if ( !$Success ) {
242                $Result{Error} = $Kernel::OM->Get('Kernel::Language')->Translate(
243                    "System was not able to reset the setting!",
244                );
245                return $Self->_ReturnJSON( Response => \%Result );
246            }
247
248            $SysConfigObject->SettingUnlock(
249                DefaultID => $Setting{DefaultID},
250            );
251        }
252
253        if (
254            ( grep { $_ eq 'reset-locally' } @Options )
255            && $SysConfigObject->can('UserSettingValueDelete')    # OTRS Business Solution™
256            )
257        {
258
259            # Remove user's value
260            my $UserValueDeleted = $SysConfigObject->UserSettingValueDelete(
261                Name       => $SettingName,
262                ModifiedID => 'All',
263                UserID     => $Self->{UserID},
264            );
265
266            if ( !$UserValueDeleted ) {
267                $Kernel::OM->Get('Kernel::System::Log')->Log(
268                    Priority => 'error',
269                    Message =>
270                        "System was not able to delete setting values for users!"
271                );
272            }
273        }
274
275        %Setting = $SysConfigObject->SettingGet(
276            Name            => $SettingName,
277            OverriddenInXML => 1,
278            UserID          => $Self->{UserID},
279        );
280
281        # Send only useful setting attributes to reduce amount of data transfered in the AJAX call.
282        for my $Key (qw(IsModified IsDirty IsLocked ExclusiveLockGUID IsValid UserModificationActive)) {
283            $Result{Data}->{SettingData}->{$Key} = $Setting{$Key};
284        }
285
286        $Result{Data}->{HTMLStrg} = $SysConfigObject->SettingRender(
287            Setting => \%Setting,
288            RW      => $Setting{ExclusiveLockGUID} ? 1 : 0,
289            UserID  => $Self->{UserID},
290        );
291
292        $Result{DeploymentNeeded} = 1;
293
294        if ( !$Result{Error} ) {
295            $Result{DeploymentNeeded} = $SysConfigObject->ConfigurationIsDirtyCheck();
296        }
297
298        if ( $Result{Data}->{HTMLStrg} =~ m{BadEffectiveValue}gsmx ) {
299            $Result{Data}->{SettingData}->{Invalid} = 1;
300        }
301
302        return $Self->_ReturnJSON( Response => \%Result );
303    }
304
305    elsif ( $Self->{Subaction} eq 'SettingUpdate' ) {
306
307        # Challenge token check for write action.
308        $LayoutObject->ChallengeTokenCheck();
309
310        my $ParamObject = $Kernel::OM->Get('Kernel::System::Web::Request');
311
312        my $SettingName            = $ParamObject->GetParam( Param => 'SettingName' ) || '';
313        my $EffectiveValueJSON     = $ParamObject->GetParam( Param => 'EffectiveValue' );
314        my $IsValid                = $ParamObject->GetParam( Param => 'IsValid' );
315        my $UserModificationActive = $ParamObject->GetParam( Param => 'UserModificationActive' );
316
317        my $EffectiveValue;
318
319        if ( !defined $EffectiveValueJSON ) {
320            $EffectiveValue = undef;
321        }
322        elsif (
323            !$EffectiveValueJSON
324            || $EffectiveValueJSON eq '"0"'
325
326            )
327        {
328            $EffectiveValue = 0;
329        }
330        elsif ( $EffectiveValueJSON eq '""' ) {
331            $EffectiveValue = '';
332        }
333        else {
334            $EffectiveValue = $Kernel::OM->Get('Kernel::System::JSON')->Decode(
335                Data => $EffectiveValueJSON,
336            );
337        }
338
339        my %Result;
340
341        # Get setting
342        my %Setting = $SysConfigObject->SettingGet(
343            Name => $SettingName,
344        );
345
346        # try to lock to the current user
347        if (
348            !$Setting{ExclusiveLockUserID}
349            ||
350            (
351                $Setting{ExclusiveLockUserID} &&
352                $Setting{ExclusiveLockUserID} != $Self->{UserID}
353            )
354            )
355        {
356            my $ExclusiveLockGUID = $SysConfigObject->SettingLock(
357                DefaultID => $Setting{DefaultID},
358                UserID    => $Self->{UserID},
359            );
360
361            if ($ExclusiveLockGUID) {
362                $Setting{ExclusiveLockGUID} = $ExclusiveLockGUID;
363            }
364            else {
365                $Result{Data}->{Error} = $Kernel::OM->Get('Kernel::Language')->Translate(
366                    "System was unable to update setting!",
367                );
368                return $Self->_ReturnJSON( Response => \%Result );
369            }
370        }
371
372        # Detect if IsValid state is different (user pressed enable or disable).
373        my $NoValidation = $IsValid // $Setting{IsValid};
374        $NoValidation = $NoValidation != $Setting{IsValid};
375
376        # Try to Update.
377        my %UpdateResult = $SysConfigObject->SettingUpdate(
378            Name                   => $SettingName,
379            EffectiveValue         => $EffectiveValue,
380            ExclusiveLockGUID      => $Setting{ExclusiveLockGUID},
381            UserID                 => $Self->{UserID},
382            IsValid                => $IsValid // $Setting{IsValid},
383            UserModificationActive => $UserModificationActive,
384            NoValidation           => $NoValidation,
385        );
386
387        if ( !$UpdateResult{Success} && !$UpdateResult{Error} ) {
388            $Result{Data}->{Error} = $Kernel::OM->Get('Kernel::Language')->Translate(
389                "System was unable to update setting!",
390            );
391        }
392        elsif ( !$UpdateResult{Success} ) {
393            $Result{Data}->{Error} = $UpdateResult{Error};
394
395            my %LockStatus = $SysConfigObject->SettingLockCheck(
396                DefaultID           => $Setting{DefaultID},
397                ExclusiveLockGUID   => $Setting{ExclusiveLockGUID},
398                ExclusiveLockUserID => $Self->{UserID},
399            );
400
401            # If LockStatus{Locked} = 2, setting is locked to the current user.
402            $Result{Data}->{SettingData}->{IsLockedByMe} = $LockStatus{Locked} == 2 ? 1 : 0;
403        }
404
405        my %UpdatedSetting = $SysConfigObject->SettingGet(
406            Name            => $SettingName,
407            OverriddenInXML => 1,
408            UserID          => $Self->{UserID},
409        );
410
411        $Result{Data}->{HTMLStrg} = $SysConfigObject->SettingRender(
412            Setting => \%UpdatedSetting,
413            RW      => $UpdatedSetting{ExclusiveLockGUID} ? 1 : 0,
414            UserID  => $Self->{UserID},
415        );
416
417        for my $Key (qw(IsModified IsDirty ExclusiveLockGUID IsValid UserModificationActive)) {
418            $Result{Data}->{SettingData}->{$Key} = $UpdatedSetting{$Key};
419        }
420
421        $Result{Data}->{DeploymentNeeded} = $SysConfigObject->ConfigurationIsDirtyCheck();
422
423        if ( $Result{Data}->{HTMLStrg} =~ m{BadEffectiveValue}gsmx ) {
424            $Result{Data}->{SettingData}->{Invalid} = 1;
425        }
426
427        return $Self->_ReturnJSON( Response => \%Result );
428    }
429    elsif ( $Self->{Subaction} eq 'SettingList' ) {
430
431        # Challenge token check for write action.
432        $LayoutObject->ChallengeTokenCheck();
433
434        my $ParamObject    = $Kernel::OM->Get('Kernel::System::Web::Request');
435        my $RootNavigation = $ParamObject->GetParam( Param => 'RootNavigation' ) || '';
436        my $Category       = $ParamObject->GetParam( Param => 'Category' ) || '';
437        $Category = $Category eq 'All' ? '' : $Category;
438
439        # Get all settings by navigation group
440        my @SettingList = $SysConfigObject->ConfigurationListGet(
441            Navigation      => $RootNavigation,
442            Translate       => 0,
443            Category        => $Category,
444            OverriddenInXML => 1,
445            UserID          => $Self->{UserID},
446        );
447
448        # get favorites from user preferences
449        my $Favourites;
450        my %UserPreferences = $Kernel::OM->Get('Kernel::System::User')->GetPreferences(
451            UserID => $Self->{UserID},
452        );
453
454        if ( $UserPreferences{UserSystemConfigurationFavourites} ) {
455            $Favourites = $Kernel::OM->Get('Kernel::System::JSON')
456                ->Decode( Data => $UserPreferences{UserSystemConfigurationFavourites} );
457        }
458
459        for my $Setting (@SettingList) {
460            my %LockStatus = $SysConfigObject->SettingLockCheck(
461                DefaultID           => $Setting->{DefaultID},
462                ExclusiveLockGUID   => $Setting->{ExclusiveLockGUID} || '1',
463                ExclusiveLockUserID => $Self->{UserID},
464            );
465
466            # TODO: This expression is slow, needs to be updated.
467            # append status
468            %{$Setting} = (
469                %{$Setting},
470                %LockStatus,
471            );
472
473            # check if this setting is a favorite of the current user
474            if ( grep { $_ eq $Setting->{Name} } @{$Favourites} ) {
475                $Setting->{IsFavourite} = 1;
476            }
477
478            $Setting->{HTMLStrg} = $SysConfigObject->SettingRender(
479                Setting => $Setting,
480                RW      => ( $Setting->{Locked} && $Setting->{Locked} == 2 ) ? 1 : 0,
481                UserID  => $Self->{UserID},
482                IsAjax  => 1,
483            );
484
485            if ( $Setting->{HTMLStrg} =~ m{BadEffectiveValue}gsmx ) {
486                $Setting->{Invalid} = 1;
487            }
488        }
489
490        my $Output = $LayoutObject->Output(
491            TemplateFile => 'SystemConfiguration/SettingsList',
492            Data         => {
493                SettingList             => \@SettingList,
494                OTRSBusinessIsInstalled => $Kernel::OM->Get('Kernel::System::OTRSBusiness')->OTRSBusinessIsInstalled(),
495                ConfigLevel             => $ConfigLevel
496            },
497        );
498
499        return $LayoutObject->Attachment(
500            NoCache     => 1,
501            ContentType => 'text/html',
502            Charset     => $LayoutObject->{UserCharset},
503            Content     => $Output || '',
504            Type        => 'inline',
505        );
506    }
507    elsif ( $Self->{Subaction} eq 'AddArrayItem' ) {
508
509        # challenge token check for write action
510        $LayoutObject->ChallengeTokenCheck();
511
512        my $ParamObject = $Kernel::OM->Get('Kernel::System::Web::Request');
513        my $SettingName = $ParamObject->GetParam( Param => 'SettingName' ) || '';
514
515        my $IDSuffix  = $ParamObject->GetParam( Param => 'IDSuffix' )  || '';
516        my $Structure = $ParamObject->GetParam( Param => 'Structure' ) || '';
517
518        my @SettingStructure = split '\.', $Structure;
519        pop @SettingStructure;
520
521        my %Result;
522        if ( !$SettingName ) {
523            $Result{Error} = Translatable("Missing setting name.");
524            return $Self->_ReturnJSON( Response => \%Result );
525        }
526
527        my %Setting = $SysConfigObject->SettingGet(
528            Name => $SettingName,
529        );
530
531        if ( !%Setting ) {
532            $Result{Error} = Translatable("Setting not found.");
533            return $Self->_ReturnJSON( Response => \%Result );
534        }
535
536        my $Value = $Setting{XMLContentParsed}->{Value}->[0];
537
538        %Result = $SysConfigObject->SettingAddItem(
539            Value            => $Value,
540            IDSuffix         => $IDSuffix,
541            SettingStructure => \@SettingStructure,
542            Setting          => \%Setting,
543            UserID           => $Self->{UserID},
544        );
545
546        if ( $Result{Item} =~ m{(input|select)} ) {
547            $Result{IsComplex} = 0;
548        }
549        else {
550            $Result{IsComplex} = 1;
551        }
552
553        return $Self->_ReturnJSON( Response => \%Result );
554    }
555    elsif ( $Self->{Subaction} eq 'AddHashKey' ) {
556
557        # Challenge token check for write action.
558        $LayoutObject->ChallengeTokenCheck();
559
560        my $ParamObject = $Kernel::OM->Get('Kernel::System::Web::Request');
561        my $SettingName = $ParamObject->GetParam( Param => 'SettingName' ) || '';
562        my $Key         = $ParamObject->GetParam( Param => 'Key' ) || '';
563
564        my $IDSuffix  = $ParamObject->GetParam( Param => 'IDSuffix' )  || '';
565        my $Structure = $ParamObject->GetParam( Param => 'Structure' ) || '';
566
567        my @SettingStructure = split '\.', $Structure;
568        pop @SettingStructure;
569
570        my %Result;
571        for my $Needed (qw(Name Key)) {
572            if ( !$Needed ) {
573                $Result{Error} = Translatable("Missing setting $Needed.");
574                return $Self->_ReturnJSON( Response => \%Result );
575            }
576        }
577
578        my %Setting = $SysConfigObject->SettingGet(
579            Name => $SettingName,
580        );
581
582        if ( !%Setting ) {
583            $Result{Error} = Translatable("Setting not found.");
584            return $Self->_ReturnJSON( Response => \%Result );
585        }
586
587        my $Value = $Setting{XMLContentParsed}->{Value}->[0];
588
589        %Result = $SysConfigObject->SettingAddItem(
590            Value             => $Value,
591            IDSuffix          => $IDSuffix,
592            SettingStructure  => \@SettingStructure,
593            Setting           => \%Setting,
594            Key               => $Key,
595            AddSettingContent => 1,
596            UserID            => $Self->{UserID},
597        );
598
599        return $Self->_ReturnJSON( Response => \%Result );
600    }
601    elsif ( $Self->{Subaction} eq 'CheckSettings' ) {
602
603        # Challenge token check for write action.
604        $LayoutObject->ChallengeTokenCheck();
605
606        my $SettingsJSON = $Kernel::OM->Get('Kernel::System::Web::Request')->GetParam(
607            Param => 'Settings'
608        );
609
610        my %Result = ( Data => [] );
611
612        if ( !$SettingsJSON ) {
613            $Result{Error} = $Kernel::OM->Get('Kernel::Language')->Translate(
614                "Missing Settings!",
615            );
616            return $Self->_ReturnJSON( Response => \%Result );
617        }
618
619        my $Settings = $Kernel::OM->Get('Kernel::System::JSON')->Decode(
620            Data => $SettingsJSON,
621        );
622
623        if ( !IsArrayRefWithData($Settings) ) {
624            return $Self->_ReturnJSON( Response => \%Result );
625        }
626
627        my $SysConfigObject = $Kernel::OM->Get('Kernel::System::SysConfig');
628
629        my @UpdatedSettingsList = $SysConfigObject->SettingsUpdatedList(
630            Settings => $Settings,
631            UserID   => $Self->{UserID},
632        );
633
634        for my $Setting (@UpdatedSettingsList) {
635
636            my %UpdatedSetting = $SysConfigObject->SettingGet(
637                Name            => $Setting->{SettingName},
638                OverriddenInXML => 1,
639                UserID          => $Self->{UserID},
640            );
641
642            my %Item;
643
644            $Item{SettingData}->{IsLockedByAnotherUser} = $Setting->{IsLockedByAnotherUser};
645            for my $Key (qw(ExclusiveLockGUID IsModified IsDirty IsValid UserModificationActive)) {
646                $Item{SettingData}->{$Key} = $UpdatedSetting{$Key};
647            }
648
649            $Item{HTMLStrg} = $SysConfigObject->SettingRender(
650                Setting => \%UpdatedSetting,
651                UserID  => $Self->{UserID},
652            );
653
654            $Item{SettingData}->{DefaultID} = $UpdatedSetting{DefaultID};
655
656            if ( $Item{HTMLStrg} =~ m{BadEffectiveValue}gsmx ) {
657                $Item{SettingData}->{Invalid} = 1;
658            }
659
660            push @{ $Result{Data} }, \%Item;
661        }
662
663        return $Self->_ReturnJSON( Response => \%Result );
664    }
665
666    # Show the content of a group with all settings.
667    my $Output = $LayoutObject->Header();
668    $Output .= $LayoutObject->NavigationBar();
669
670    my $RootNavigation = $ParamObject->GetParam( Param => 'RootNavigation' ) || '';
671
672    # Get path structure to show in the bread crumbs
673    my @Path = $SysConfigObject->SettingNavigationToPath(
674        Navigation => $RootNavigation,
675    );
676
677    # Get navigation tree
678    my %Tree = $SysConfigObject->ConfigurationNavigationTree();
679
680    my $Category = $ParamObject->GetParam( Param => 'Category' ) || '';
681    $Category = $Category eq 'All' ? '' : $Category;
682
683    # Get all settings by navigation group
684    my @SettingList = $SysConfigObject->ConfigurationListGet(
685        Navigation      => $RootNavigation,
686        Translate       => 0,
687        Category        => $Category,
688        OverriddenInXML => 1,
689        UserID          => $Self->{UserID},
690    );
691
692    # get favorites from user preferences
693    my $Favourites;
694    my %UserPreferences = $Kernel::OM->Get('Kernel::System::User')->GetPreferences(
695        UserID => $Self->{UserID},
696    );
697
698    if ( $UserPreferences{UserSystemConfigurationFavourites} ) {
699        $Favourites = $Kernel::OM->Get('Kernel::System::JSON')
700            ->Decode( Data => $UserPreferences{UserSystemConfigurationFavourites} );
701    }
702
703    for my $Setting (@SettingList) {
704        my %LockStatus = $SysConfigObject->SettingLockCheck(
705            DefaultID           => $Setting->{DefaultID},
706            ExclusiveLockGUID   => $Setting->{ExclusiveLockGUID} || '1',
707            ExclusiveLockUserID => $Self->{UserID},
708        );
709
710        # append status
711        %{$Setting} = (
712            %{$Setting},
713            %LockStatus,
714        );
715
716        # check if this setting is a favorite of the current user
717        if ( grep { $_ eq $Setting->{Name} } @{$Favourites} ) {
718            $Setting->{IsFavourite} = 1;
719        }
720
721        $Setting->{HTMLStrg} = $SysConfigObject->SettingRender(
722            Setting => $Setting,
723            RW      => ( $Setting->{Locked} && $Setting->{Locked} == 2 ) ? 1 : 0,
724            UserID  => $Self->{UserID},
725        );
726
727        if ( $Setting->{HTMLStrg} =~ m{BadEffectiveValue}gsmx ) {
728            $Setting->{Invalid} = 1;
729        }
730    }
731
732    $Output .= $LayoutObject->Output(
733        TemplateFile => 'AdminSystemConfigurationGroup',
734        Data         => {
735            Tree                    => \%Tree,
736            Path                    => \@Path,
737            RootNavigation          => $RootNavigation,
738            SettingList             => \@SettingList,
739            CategoriesStrg          => $Self->_GetCategoriesStrg(),
740            InvalidSettings         => $Self->_CheckInvalidSettings(),
741            OTRSBusinessIsInstalled => $Kernel::OM->Get('Kernel::System::OTRSBusiness')->OTRSBusinessIsInstalled(),
742            ConfigLevel             => $ConfigLevel,
743        },
744    );
745    $Output .= $LayoutObject->Footer();
746
747    return $Output;
748}
749
750sub _GetCategoriesStrg {
751    my ( $Self, %Param ) = @_;
752
753    # get selected category
754    my %UserPreferences = $Kernel::OM->Get('Kernel::System::User')->GetPreferences(
755        UserID => $Self->{UserID},
756    );
757
758    my $Category = $UserPreferences{UserSystemConfigurationCategory};
759
760    my %Categories = $Kernel::OM->Get('Kernel::System::SysConfig')->ConfigurationCategoriesGet();
761
762    my %CategoryData = map { $_ => $Categories{$_}->{DisplayName} } keys %Categories;
763
764    my $CategoriesStrg = $Kernel::OM->Get('Kernel::Output::HTML::Layout')->BuildSelection(
765        Data         => \%CategoryData,
766        Name         => 'Category',
767        SelectedID   => $Category || 'All',
768        PossibleNone => 0,
769        Translation  => 1,
770        Sort         => 'AlphaNumericKey',
771        Class        => 'Modernize',
772        Title        => $Kernel::OM->Get('Kernel::Language')->Translate('Category Search'),
773    );
774
775    return $CategoriesStrg;
776}
777
778sub _ReturnJSON {
779    my ( $Self, %Param ) = @_;
780
781    for my $Needed (qw(Response)) {
782        if ( !$Param{$Needed} ) {
783            $Kernel::OM->Get('Kernel::System::Log')->Log(
784                Priority => 'error',
785                Message  => "Need $Needed!",
786            );
787            return;
788        }
789    }
790
791    # JSON response
792    my $JSON = $Kernel::OM->Get('Kernel::System::JSON')->Encode(
793        Data => $Param{Response},
794    );
795
796    my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
797
798    return $LayoutObject->Attachment(
799        ContentType => 'application/json; charset=' . $LayoutObject->{Charset},
800        Content     => $JSON,
801        Type        => 'inline',
802        NoCache     => 1,
803    );
804}
805
806sub _CheckInvalidSettings {
807    my ( $Self, %Param ) = @_;
808
809    my @InvalidSettings = $Kernel::OM->Get('Kernel::System::SysConfig')->ConfigurationInvalidList(
810        CachedOnly => 1,
811    );
812
813    return 0 if !@InvalidSettings;
814
815    return 1;
816}
817
8181;
819