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::AgentPreferences;
10
11use strict;
12use warnings;
13
14our $ObjectManagerDisabled = 1;
15
16use Kernel::System::VariableCheck qw(:all);
17use Kernel::Language qw(Translatable);
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 $ParamObject  = $Kernel::OM->Get('Kernel::System::Web::Request');
34    my $UserObject   = $Kernel::OM->Get('Kernel::System::User');
35    my $EditUserID   = $ParamObject->GetParam( Param => 'EditUserID' );
36
37    $Self->{CurrentUserID} = $Self->{UserID};
38    if (
39        $EditUserID
40        && $Self->_CheckEditPreferencesPermission()
41        )
42    {
43        $Self->{CurrentUserID}       = $EditUserID;
44        $Self->{EditingAnotherAgent} = ";EditUserID=$EditUserID";
45    }
46
47    # ------------------------------------------------------------ #
48    # update preferences via AJAX
49    # ------------------------------------------------------------ #
50    if ( $Self->{Subaction} eq 'UpdateAJAX' ) {
51
52        # challenge token check for write action
53        $LayoutObject->ChallengeTokenCheck();
54
55        my $Key   = $ParamObject->GetParam( Param => 'Key' );
56        my $Value = $ParamObject->GetParam( Param => 'Value' );
57
58        # update preferences
59        my $Success = $UserObject->SetPreferences(
60            UserID => $Self->{CurrentUserID},
61            Key    => $Key,
62            Value  => $Value,
63        );
64
65        # update session
66        if ($Success) {
67            $Kernel::OM->Get('Kernel::System::AuthSession')->UpdateSessionID(
68                SessionID => $Self->{SessionID},
69                Key       => $Key,
70                Value     => $Value,
71            );
72        }
73        my $JSON = $LayoutObject->JSONEncode(
74            Data => $Success,
75        );
76        return $LayoutObject->Attachment(
77            ContentType => 'application/json; charset=' . $LayoutObject->{Charset},
78            Content     => $JSON,
79            Type        => 'inline',
80            NoCache     => 1,
81        );
82    }
83
84    # ------------------------------------------------------------ #
85    # update preferences
86    # ------------------------------------------------------------ #
87    elsif ( $Self->{Subaction} eq 'UpdateAJAXComplex' ) {
88
89        # challenge token check for write action
90        $LayoutObject->ChallengeTokenCheck();
91
92        my $Message           = '';
93        my $Priority          = '';
94        my $ConfigNeedsReload = 0;
95
96        # check group param
97        my @Groups = $ParamObject->GetArray( Param => 'Group' );
98        if ( !@Groups ) {
99            return $LayoutObject->ErrorScreen(
100                Message => Translatable('Param Group is required!'),
101            );
102        }
103
104        my $SettingID = $ParamObject->GetParam( Param => 'SettingID' );
105
106        for my $Group (@Groups) {
107
108            # check preferences setting
109            my %Preferences = %{ $Kernel::OM->Get('Kernel::Config')->Get('PreferencesGroups') };
110            if ( !$Preferences{$Group} ) {
111                return $LayoutObject->ErrorScreen(
112                    Message => $LayoutObject->{LanguageObject}->Translate( 'No such config for %s', $Group ),
113                );
114            }
115
116            # get user data
117            my %UserData = $UserObject->GetUserData( UserID => $Self->{CurrentUserID} );
118            my $Module   = $Preferences{$Group}->{Module};
119            if ( !$Kernel::OM->Get('Kernel::System::Main')->Require($Module) ) {
120                return $LayoutObject->FatalError();
121            }
122
123            my $Object = $Module->new(
124                %{$Self},
125                UserID     => $Self->{CurrentUserID},
126                UserObject => $UserObject,
127                ConfigItem => $Preferences{$Group},
128                Debug      => $Self->{Debug},
129            );
130            my @Params = $Object->Param( UserData => \%UserData );
131            my %GetParam;
132            for my $ParamItem (@Params) {
133                my @Array = $ParamObject->GetArray(
134                    Param => $ParamItem->{Name},
135                    Raw   => $ParamItem->{Raw} || 0,
136                );
137                if ( defined $ParamItem->{Name} ) {
138                    $GetParam{ $ParamItem->{Name} } = \@Array;
139                }
140            }
141
142            if (
143                $Object->Run(
144                    GetParam => \%GetParam,
145                    UserData => \%UserData
146                )
147                )
148            {
149                $Message .= $Object->Message();
150                if ( $Preferences{$Group}->{NeedsReload} ) {
151                    $ConfigNeedsReload = 1;
152                }
153            }
154            else {
155                $Priority .= 'Error';
156                $Message  .= $Object->Error();
157            }
158        }
159
160        my $JSON = $LayoutObject->JSONEncode(
161            Data => {
162                'Message'     => $Message,
163                'Priority'    => $Priority,
164                'NeedsReload' => $ConfigNeedsReload
165            },
166        );
167
168        return $LayoutObject->Attachment(
169            ContentType => 'application/json; charset=' . $LayoutObject->{Charset},
170            Content     => $JSON,
171            Type        => 'inline',
172            NoCache     => 1,
173        );
174    }
175
176    # ------------------------------------------------------------ #
177    # update preferences
178    # ------------------------------------------------------------ #
179    elsif ( $Self->{Subaction} eq 'Update' ) {
180
181        # challenge token check for write action
182        $LayoutObject->ChallengeTokenCheck();
183
184        my $Message  = '';
185        my $Priority = '';
186
187        # check group param
188        my @Groups = $ParamObject->GetArray( Param => 'Group' );
189        if ( !@Groups ) {
190            return $LayoutObject->ErrorScreen(
191                Message => Translatable('Param Group is required!'),
192            );
193        }
194
195        for my $Group (@Groups) {
196
197            # check preferences setting
198            my %Preferences = %{ $Kernel::OM->Get('Kernel::Config')->Get('PreferencesGroups') };
199            if ( !$Preferences{$Group} ) {
200                return $LayoutObject->ErrorScreen(
201                    Message => $LayoutObject->{LanguageObject}->Translate( 'No such config for %s', $Group ),
202                );
203            }
204
205            # get user data
206            my %UserData = $UserObject->GetUserData( UserID => $Self->{CurrentUserID} );
207            my $Module   = $Preferences{$Group}->{Module};
208            if ( !$Kernel::OM->Get('Kernel::System::Main')->Require($Module) ) {
209                return $LayoutObject->FatalError();
210            }
211
212            my $Object = $Module->new(
213                %{$Self},
214                UserID     => $Self->{CurrentUserID},
215                UserObject => $UserObject,
216                ConfigItem => $Preferences{$Group},
217                Debug      => $Self->{Debug},
218            );
219            my @Params = $Object->Param( UserData => \%UserData );
220            my %GetParam;
221            for my $ParamItem (@Params) {
222                my @Array = $ParamObject->GetArray(
223                    Param => $ParamItem->{Name},
224                    Raw   => $ParamItem->{Raw} || 0,
225                );
226                if ( defined $ParamItem->{Name} ) {
227                    $GetParam{ $ParamItem->{Name} } = \@Array;
228                }
229            }
230
231            if (
232                $Object->Run(
233                    GetParam => \%GetParam,
234                    UserData => \%UserData
235                )
236                )
237            {
238                $Message .= $Object->Message();
239            }
240            else {
241                $Priority .= 'Error';
242                $Message  .= $Object->Error();
243            }
244        }
245
246        # check redirect
247        my $RedirectURL = $ParamObject->GetParam( Param => 'RedirectURL' );
248        if ($RedirectURL) {
249            return $LayoutObject->Redirect(
250                OP => $RedirectURL,
251            );
252        }
253
254        # redirect
255        return $LayoutObject->Redirect(
256            OP => "Action=AgentPreferences;Priority=$Priority;Message=$Message",
257        );
258    }
259
260    elsif ( $Self->{Subaction} eq 'SettingUpdate' ) {
261
262        # challenge token check for write action
263        $LayoutObject->ChallengeTokenCheck();
264
265        my $SysConfigObject = $Kernel::OM->Get('Kernel::System::SysConfig');
266
267        my $SettingName        = $ParamObject->GetParam( Param => 'SettingName' ) || '';
268        my $EffectiveValueJSON = $ParamObject->GetParam( Param => 'EffectiveValue' );
269
270        my $EffectiveValue;
271
272        if ( !defined $EffectiveValueJSON ) {
273            $EffectiveValue = undef;
274        }
275        elsif (
276            !$EffectiveValueJSON
277            || $EffectiveValueJSON eq '"0"'
278
279            )
280        {
281            $EffectiveValue = 0;
282        }
283        else {
284            $EffectiveValue = $Kernel::OM->Get('Kernel::System::JSON')->Decode(
285                Data => $EffectiveValueJSON,
286            );
287        }
288
289        my %Setting = $SysConfigObject->SettingGet(
290            Name            => $SettingName,
291            OverriddenInXML => 1,
292            UserID          => 1,
293        );
294        my $DataIsDifferent = DataIsDifferent(
295            Data1 => $EffectiveValue,
296            Data2 => $Setting{EffectiveValue},
297        );
298
299        if ( !$DataIsDifferent ) {
300            return $Self->_SettingReset( SettingName => $SettingName );
301        }
302
303        my %Result;
304
305        my %UpdateResult = $SysConfigObject->SettingUpdate(
306            Name           => $SettingName,
307            EffectiveValue => $EffectiveValue,
308            TargetUserID   => $Self->{CurrentUserID},
309            UserID         => $Self->{CurrentUserID},
310        );
311
312        if ( $UpdateResult{Error} ) {
313            $Result{Data}->{Error} = $UpdateResult{Error};
314        }
315        elsif ( !$SysConfigObject->can('UserConfigurationDeploy') ) {    # OTRS Business Solution™
316            $Result{Data}->{Error} = $Kernel::OM->Get('Kernel::Language')->Translate(
317                "This feature is part of the %s. Please contact us at %s for an upgrade."
318                , 'OTRS Business Solution™'
319                , 'sales@otrs.com'
320            );
321        }
322        else {
323
324            # update successful, now deploy only this setting (if it's dirty)
325            my %UpdatedSetting = $SysConfigObject->SettingGet(
326                Name         => $SettingName,
327                TargetUserID => $Self->{CurrentUserID},
328            );
329
330            if ( $UpdatedSetting{IsDirty} ) {
331                my $DeploySuccess = $SysConfigObject->UserConfigurationDeploy(
332                    TargetUserID => $Self->{CurrentUserID},
333                    Comments     => Translatable('Updated user preferences'),
334                );
335
336                if ( !$DeploySuccess ) {
337                    $Result{Data}->{Error} = $Kernel::OM->Get('Kernel::Language')->Translate(
338                        "System was unable to deploy your changes.",
339                    );
340                }
341            }
342
343            # reload setting with fresh data
344            %UpdatedSetting = $SysConfigObject->SettingGet(
345                Name         => $SettingName,
346                TargetUserID => $Self->{CurrentUserID},
347            );
348
349            my $GlobalEffectiveValue = $SysConfigObject->GlobalEffectiveValueGet(
350                SettingName => $SettingName,
351            );
352
353            my $IsModified = DataIsDifferent(
354                Data1 => \$UpdatedSetting{EffectiveValue},
355                Data2 => \$GlobalEffectiveValue,
356            ) || 0;
357
358            $Result{Data}->{HTMLStrg} = $SysConfigObject->SettingRender(
359                Setting => \%UpdatedSetting,
360                RW      => 1,
361                UserID  => $Self->{UserID},
362            );
363            $Result{Data}->{SettingData}->{IsModified}        = $IsModified;
364            $Result{Data}->{SettingData}->{IsLockedByMe}      = 1;
365            $Result{Data}->{SettingData}->{ExclusiveLockGUID} = 1;
366        }
367
368        # JSON response
369        my $JSON = $Kernel::OM->Get('Kernel::System::JSON')->Encode(
370            Data => \%Result,
371        );
372
373        return $LayoutObject->Attachment(
374            ContentType => 'application/json; charset=' . $LayoutObject->{Charset},
375            Content     => $JSON,
376            Type        => 'inline',
377            NoCache     => 1,
378        );
379    }
380
381    elsif ( $Self->{Subaction} eq 'SettingReset' ) {
382
383        # challenge token check for write action
384        $LayoutObject->ChallengeTokenCheck();
385
386        my $SysConfigObject = $Kernel::OM->Get('Kernel::System::SysConfig');
387
388        my $SettingName = $ParamObject->GetParam( Param => 'SettingName' ) || '';
389
390        return $Self->_SettingReset( SettingName => $SettingName );
391    }
392
393    elsif ( $Self->{Subaction} eq 'SettingList' ) {
394
395        # challenge token check for write action
396        $LayoutObject->ChallengeTokenCheck();
397
398        my $SysConfigObject = $Kernel::OM->Get('Kernel::System::SysConfig');
399        my $RootNavigation  = $ParamObject->GetParam( Param => 'RootNavigation' ) || '';
400
401        my @SettingList = $SysConfigObject->ConfigurationListGet(
402            TargetUserID    => $Self->{CurrentUserID},
403            IsValid         => 1,
404            Navigation      => $RootNavigation // undef,
405            OverriddenInXML => 1,
406            UserID          => 1,
407        );
408
409        for my $Setting (@SettingList) {
410
411            # OverriddenFileName is used only in Admin interface.
412            delete $Setting->{OverriddenFileName};
413
414            # If the setting is overriden in the *.pm file, take it as default and update IsModified.
415            my $GlobalEffectiveValue = $SysConfigObject->GlobalEffectiveValueGet(
416                SettingName => $Setting->{Name},
417            );
418
419            my $IsModified = DataIsDifferent(
420                Data1 => \$Setting->{EffectiveValue},
421                Data2 => \$GlobalEffectiveValue,
422            ) || 0;
423
424            $Setting->{IsModified} = $IsModified;
425
426            $Setting->{HTMLStrg} = $SysConfigObject->SettingRender(
427                Setting => $Setting,
428                RW      => 1,
429                UserID  => $Self->{UserID},
430            );
431        }
432
433        my $Output = "<ul class='SettingsList Preferences'>\n";
434        $Output .= $LayoutObject->Output(
435            TemplateFile => 'AgentPreferences/SettingsList',
436            Data         => {
437                RootNavigation => $RootNavigation,
438                SettingList    => \@SettingList,
439            },
440        );
441        $Output .= "</ul>\n";
442
443        return $LayoutObject->Attachment(
444            NoCache     => 1,
445            ContentType => 'text/html',
446            Charset     => $LayoutObject->{UserCharset},
447            Content     => $Output || '',
448            Type        => 'inline',
449        );
450
451    }
452
453    # ------------------------------------------------------------ #
454    # show preferences group
455    # ------------------------------------------------------------ #
456    elsif ( $Self->{Subaction} eq 'Group' ) {
457
458        # get header
459        my $Output = $LayoutObject->Header();
460        $Output .= $LayoutObject->NavigationBar();
461
462        # get param
463        my $Message  = $ParamObject->GetParam( Param => 'Message' )  || '';
464        my $Priority = $ParamObject->GetParam( Param => 'Priority' ) || '';
465
466        # add notification
467        if ( $Message && $Priority eq 'Error' ) {
468            $Output .= $LayoutObject->Notify(
469                Priority => $Priority,
470                Info     => $Message,
471            );
472        }
473        elsif ($Message) {
474            $Output .= $LayoutObject->Notify(
475                Info => $Message,
476            );
477        }
478
479        # get user data
480        my %UserData = $UserObject->GetUserData( UserID => $Self->{CurrentUserID} );
481        $Output .= $Self->AgentPreferencesForm( UserData => \%UserData );
482        $Output .= $LayoutObject->Footer();
483
484        return $Output;
485    }
486
487    # ------------------------------------------------------------ #
488    # Return user favourite system configuration settings.
489    # ------------------------------------------------------------ #
490    elsif ( $Self->{Subaction} eq 'UserSystemConfigurationFavourites' ) {
491
492        my $Favourites      = [];
493        my %UserPreferences = $Kernel::OM->Get('Kernel::System::User')->GetPreferences(
494            UserID => $Self->{UserID},
495        );
496
497        if ( $UserPreferences{UserSystemConfigurationFavourites} ) {
498            $Favourites = $Kernel::OM->Get('Kernel::System::JSON')
499                ->Decode( Data => $UserPreferences{UserSystemConfigurationFavourites} );
500        }
501
502        my $JSON = $Kernel::OM->Get('Kernel::System::JSON')->Encode(
503            Data => $Favourites,
504        );
505
506        return $LayoutObject->Attachment(
507            ContentType => 'application/json; charset=' . $LayoutObject->{Charset},
508            Content     => $JSON,
509            Type        => 'inline',
510            NoCache     => 1,
511        );
512    }
513
514    # ------------------------------------------------------------ #
515    # show AJAX navigation tree
516    # ------------------------------------------------------------ #
517    if ( $Self->{Subaction} eq 'AJAXNavigationTree' ) {
518
519        my $Category               = $ParamObject->GetParam( Param => 'Category' )               || '';
520        my $UserModificationActive = $ParamObject->GetParam( Param => 'UserModificationActive' ) || '0';
521        my $IsValid = $ParamObject->GetParam( Param => 'IsValid' ) // undef;
522
523        my %Tree = $Kernel::OM->Get('Kernel::System::SysConfig')->ConfigurationNavigationTree(
524            Action                 => 'AgentPreferences',
525            Category               => $Category,
526            UserModificationActive => $UserModificationActive,
527            IsValid                => $IsValid,
528        );
529
530        my $Output = $LayoutObject->Output(
531            TemplateFile => 'SystemConfiguration/NavigationTree',
532            Data         => {
533                Tree => \%Tree,
534            },
535        );
536
537        return $LayoutObject->Attachment(
538            NoCache     => 1,
539            ContentType => 'text/html',
540            Charset     => $LayoutObject->{UserCharset},
541            Content     => $Output || '',
542            Type        => 'inline',
543        );
544    }
545
546    # ------------------------------------------------------------ #
547    # show group overview
548    # ------------------------------------------------------------ #
549    else {
550
551        # get header
552        my $Output = $LayoutObject->Header();
553        $Output .= $LayoutObject->NavigationBar();
554
555        # get groups
556        my @PreferencesGroups = @{ $Kernel::OM->Get('Kernel::Config')->Get('AgentPreferencesGroups') };
557        if (@PreferencesGroups) {
558            @PreferencesGroups = sort { $a->{Prio} <=> $b->{Prio} } @PreferencesGroups;
559        }
560
561        my %UserPreferences = $Kernel::OM->Get('Kernel::System::User')->GetPreferences(
562            UserID => $Self->{CurrentUserID},
563        );
564
565        $Output .= $LayoutObject->Output(
566            TemplateFile => 'AgentPreferencesOverview',
567            Data         => {
568                Items               => \@PreferencesGroups,
569                EditingAnotherAgent => $Self->{EditingAnotherAgent},
570                CurrentUserFullname => $UserObject->UserName( UserID => $Self->{CurrentUserID} ),
571                CurrentUserID       => $Self->{CurrentUserID},
572                View                => $UserPreferences{AgentPreferencesView} || 'Grid',
573            },
574        );
575
576        $Output .= $LayoutObject->Footer();
577
578        return $Output;
579    }
580}
581
582sub AgentPreferencesForm {
583    my ( $Self, %Param ) = @_;
584
585    my $LayoutObject    = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
586    my $SysConfigObject = $Kernel::OM->Get('Kernel::System::SysConfig');
587    my $ParamObject     = $Kernel::OM->Get('Kernel::System::Web::Request');
588
589    my $GroupSelected  = $ParamObject->GetParam( Param => 'Group' )          || 'UserProfile';
590    my $RootNavigation = $ParamObject->GetParam( Param => 'RootNavigation' ) || '';
591    my $EditUserID     = $ParamObject->GetParam( Param => 'EditUserID' );
592
593    my @Path = $SysConfigObject->SettingNavigationToPath(
594        Navigation => $RootNavigation,
595    );
596    $Param{Path} = \@Path;
597
598    $Self->{CurrentUserID} = $Self->{UserID};
599    if (
600        $EditUserID
601        && $Self->_CheckEditPreferencesPermission()
602        )
603    {
604        $Self->{EditingAnotherAgent} = ";EditUserID=$EditUserID";
605        $Self->{CurrentUserID}       = $EditUserID;
606    }
607
608    # Show navigation in advanced group
609    if ( $GroupSelected eq 'Advanced' ) {
610        $Param{Navigation} = 1;
611
612        my @SettingList = $SysConfigObject->ConfigurationListGet(
613            TargetUserID    => $Self->{CurrentUserID},
614            IsValid         => 1,
615            Navigation      => $RootNavigation // undef,
616            OverriddenInXML => 1,
617            Translate       => 0,
618            UserID          => 1,
619        );
620
621        for my $Setting (@SettingList) {
622
623            # OverriddenFileName is used only in Admin interface.
624            delete $Setting->{OverriddenFileName};
625
626            # If the setting is overriden in the *.pm file, take it as default and update IsModified.
627            my $GlobalEffectiveValue = $SysConfigObject->GlobalEffectiveValueGet(
628                SettingName => $Setting->{Name},
629            );
630
631            my $IsModified = DataIsDifferent(
632                Data1 => \$Setting->{EffectiveValue},
633                Data2 => \$GlobalEffectiveValue,
634            ) || 0;
635
636            $Setting->{IsModified} = $IsModified;
637
638            $Setting->{HTMLStrg} = $SysConfigObject->SettingRender(
639                Setting => $Setting,
640                RW      => 1,
641                UserID  => $Self->{UserID},
642            );
643        }
644
645        $Param{SettingList} = \@SettingList;
646    }
647
648    # get group name
649    my @PreferencesGroups = @{ $Kernel::OM->Get('Kernel::Config')->Get('AgentPreferencesGroups') };
650    my $GroupSelectedName;
651
652    PREFERENCESGROUPS:
653    for my $Group (@PreferencesGroups) {
654        next PREFERENCESGROUPS if $Group->{Key} ne $GroupSelected;
655        $GroupSelectedName = $Group->{Name};
656    }
657
658    $LayoutObject->Block(
659        Name => 'Body',
660        Data => {
661            GroupKey  => $GroupSelected,
662            GroupName => $GroupSelectedName,
663            %Param,
664            CategoriesStrg      => $Self->_GetCategoriesStrg(),
665            RootNavigation      => $RootNavigation,
666            EditingAnotherAgent => $Self->{EditingAnotherAgent},
667            CurrentUserFullname =>
668                $Kernel::OM->Get('Kernel::System::User')->UserName( UserID => $Self->{CurrentUserID} ),
669            CurrentUserID => $Self->{CurrentUserID},
670        },
671    );
672
673    my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
674    my %Data;
675    my %Preferences = %{ $ConfigObject->Get('PreferencesGroups') };
676
677    GROUP:
678    for my $Group ( sort keys %Preferences ) {
679
680        next GROUP if !$Group;
681        next GROUP if !$Preferences{$Group};
682        next GROUP if ref $Preferences{$Group} ne 'HASH';
683        next GROUP if !$Preferences{$Group}->{PreferenceGroup};
684        next GROUP if $Preferences{$Group}->{PreferenceGroup} ne $GroupSelected;
685
686        # In case of a priority conflict, increase priority until a free slot is found.
687        if ( $Data{ $Preferences{$Group}->{Prio} } ) {
688
689            COUNT:
690            for ( 1 .. 151 ) {
691
692                $Preferences{$Group}->{Prio}++;
693
694                next COUNT if $Data{ $Preferences{$Group}->{Prio} };
695
696                $Data{ $Preferences{$Group}->{Prio} } = $Group;
697                last COUNT;
698            }
699        }
700
701        $Data{ $Preferences{$Group}->{Prio} } = $Group;
702    }
703
704    # sort
705    for my $Key ( sort keys %Data ) {
706        $Data{ sprintf( "%07d", $Key ) } = $Data{$Key};
707        delete $Data{$Key};
708    }
709
710    # show each preferences setting
711    PRIO:
712    for my $Prio ( sort keys %Data ) {
713        my $Group = $Data{$Prio};
714        next PRIO if !$ConfigObject->{PreferencesGroups}->{$Group};
715
716        my %Preference = %{ $ConfigObject->{PreferencesGroups}->{$Group} };
717
718        if ( !$Self->{EditingAnotherAgent} && !$Preference{Active} ) {
719            next PRIO;
720        }
721
722        # load module
723        my $Module = $Preference{Module} || 'Kernel::Output::HTML::Preferences::Generic';
724        if ( !$Kernel::OM->Get('Kernel::System::Main')->Require($Module) ) {
725            return $LayoutObject->FatalError();
726        }
727
728        # create a new module object
729        my $Object;
730        eval {
731            $Object = $Module->new(
732                %{$Self},
733                UserID     => $Self->{CurrentUserID},
734                UserObject => $Kernel::OM->Get('Kernel::System::User'),
735                ConfigItem => \%Preference,
736                Debug      => $Self->{Debug},
737            );
738        };
739        if ($@) {
740            $Kernel::OM->Get('Kernel::System::Log')->Log(
741                Priority => 'error',
742                Message  => "Could not create a new object for $Group Error: $@",
743            );
744        }
745        next PRIO if !$Object;
746
747        # get params for the new module object
748        my @Params;
749        eval {
750            @Params = $Object->Param( UserData => $Param{UserData} );
751        };
752        if ($@) {
753            $Kernel::OM->Get('Kernel::System::Log')->Log(
754                Priority => 'error',
755                Message  => "Could not get params from $Group Error: $@",
756            );
757        }
758        next PRIO if !@Params;
759
760        # show item
761        $LayoutObject->Block(
762            Name => 'Item',
763            Data => {
764                Group      => $Group,
765                EditUserID => $Self->{CurrentUserID},
766                %Preference,
767            },
768        );
769
770        for my $ParamItem (@Params) {
771            if ( ref $ParamItem->{Data} eq 'HASH' || ref $Preference{Data} eq 'HASH' ) {
772                my %BuildSelectionParams = (
773                    %Preference,
774                    %{$ParamItem},
775                    OptionTitle => 1,
776                );
777                $BuildSelectionParams{Class} = join( ' ', $BuildSelectionParams{Class} // '', 'Modernize' );
778                $ParamItem->{Option} = $LayoutObject->BuildSelection(
779                    %BuildSelectionParams,
780                );
781            }
782            $LayoutObject->Block(
783                Name => 'Block',
784                Data => { %Preference, %{$ParamItem}, },
785            );
786            my $BlockName = $ParamItem->{Block} || $Preference{Block} || 'Option';
787
788            $LayoutObject->Block(
789                Name => $BlockName,
790                Data => { %Preference, %{$ParamItem}, },
791            );
792
793            if ( scalar @Params == 1 ) {
794                $LayoutObject->Block(
795                    Name => $BlockName . 'SingleBlock',
796                    Data => { %Preference, %{$ParamItem}, },
797                );
798            }
799        }
800
801        if ( scalar @Params > 1 ) {
802            $LayoutObject->Block(
803                Name => 'MultipleBlocks',
804                Data => {%Preference},
805            );
806        }
807    }
808
809    # create & return output
810    return $LayoutObject->Output(
811        TemplateFile => 'AgentPreferences',
812        Data         => {
813            %Param,
814        },
815    );
816}
817
818sub _GetCategoriesStrg {
819    my ( $Self, %Param ) = @_;
820
821    # get selected category
822    my %UserPreferences = $Kernel::OM->Get('Kernel::System::User')->GetPreferences(
823        UserID => $Self->{UserID},
824    );
825
826    my $Category = $UserPreferences{UserSystemConfigurationCategory};
827
828    my %Categories = $Kernel::OM->Get('Kernel::System::SysConfig')->ConfigurationCategoriesGet();
829
830    my %CategoryData = map { $_ => $Categories{$_}->{DisplayName} } keys %Categories;
831
832    my $CategoriesStrg = $Kernel::OM->Get('Kernel::Output::HTML::Layout')->BuildSelection(
833        Data         => \%CategoryData,
834        Name         => 'Category',
835        SelectedID   => $Category || 'All',
836        PossibleNone => 0,
837        Translation  => 1,
838        Sort         => 'AlphaNumericKey',
839        Class        => 'Modernize',
840        Title        => $Kernel::OM->Get('Kernel::Language')->Translate('Category Search'),
841    );
842
843    return $CategoriesStrg;
844}
845
846sub _CheckEditPreferencesPermission {
847
848    my ( $Self, %Param ) = @_;
849
850    # check if the current user has the permissions to edit another users preferences
851    my $GroupObject                      = $Kernel::OM->Get('Kernel::System::Group');
852    my $EditAnotherUsersPreferencesGroup = $GroupObject->GroupLookup(
853        Group => $Kernel::OM->Get('Kernel::Config')->Get('EditAnotherUsersPreferencesGroup'),
854    );
855
856    # get user groups, where the user has the rw privilege
857    my %Groups = $GroupObject->PermissionUserGet(
858        UserID => $Self->{UserID},
859        Type   => 'rw',
860    );
861
862    # if the user is a member in this group he can access the feature
863    if ( $Groups{$EditAnotherUsersPreferencesGroup} ) {
864        return 1;
865    }
866
867    return 0;
868}
869
870sub _SettingReset {
871    my ( $Self, %Param ) = @_;
872
873    my $SettingName = $Param{SettingName};
874
875    my $SysConfigObject = $Kernel::OM->Get('Kernel::System::SysConfig');
876
877    my %Setting = $SysConfigObject->SettingGet(
878        Name            => $SettingName,
879        TargetUserID    => $Self->{CurrentUserID},
880        OverriddenInXML => 1,
881        UserID          => 1,
882    );
883
884    # OverriddenFileName is used only in Admin interface.
885    delete $Setting{OverriddenFileName};
886
887    my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
888
889    my %Result;
890
891    if ( !%Setting ) {
892        $Result{Error} = $LayoutObject->{LanguageObject}->Translate("Setting not found!");
893    }
894    elsif ( !$SysConfigObject->can('UserSettingValueDelete') ) {    # OTRS Business Solution™
895        $Result{Data}->{Error} = $LayoutObject->{LanguageObject}->Translate(
896            "This feature is part of the %s. Please contact us at %s for an upgrade."
897            , 'OTRS Business Solution™'
898            , 'sales@otrs.com'
899        );
900    }
901    elsif ( $Setting{ModifiedID} ) {
902
903        # Remove user's value
904        my $UserValueDeleted = $SysConfigObject->UserSettingValueDelete(
905            Name       => $SettingName,
906            ModifiedID => $Setting{ModifiedID},
907            UserID     => $Self->{UserID},
908        );
909
910        if ($UserValueDeleted) {
911
912            # Get setting value after reset
913            %Setting = $SysConfigObject->SettingGet(
914                Name         => $SettingName,
915                TargetUserID => $Self->{CurrentUserID},
916            );
917
918            # If the setting is overriden in the *.pm file, take it as default and update IsModified.
919            my $GlobalEffectiveValue = $SysConfigObject->GlobalEffectiveValueGet(
920                SettingName => $SettingName,
921            );
922
923            $Setting{EffectiveValue} = $GlobalEffectiveValue;
924
925            $Result{Data}->{HTMLStrg} = $SysConfigObject->SettingRender(
926                Setting => \%Setting,
927                RW      => 1,
928                UserID  => $Self->{UserID},
929            );
930            $Result{Data}->{SettingData}->{IsModified}   = 0;
931            $Result{Data}->{SettingData}->{IsLockedByMe} = 1;
932        }
933        else {
934            $Result{Data}->{HTMLStrg} = $SysConfigObject->SettingRender(
935                Setting => \%Setting,
936                RW      => 1,
937                UserID  => $Self->{UserID},
938            );
939            $Result{Data}->{SettingData}->{IsModified}   = 1;
940            $Result{Data}->{SettingData}->{IsLockedByMe} = 1;
941            $Result{Error}                               = $LayoutObject->{LanguageObject}->Translate(
942                "System was unable to reset the setting!",
943            );
944        }
945    }
946    else {
947        $Result{Data}->{HTMLStrg} = $SysConfigObject->SettingRender(
948            Setting => \%Setting,
949            RW      => 1,
950            UserID  => $Self->{UserID},
951        );
952
953        $Result{Data}->{SettingData}->{IsLockedByMe} = 1;
954        $Result{Error} = $LayoutObject->{LanguageObject}->Translate(
955            "System was unable to reset the setting!",
956        );
957    }
958
959    # JSON response
960    my $JSON = $Kernel::OM->Get('Kernel::System::JSON')->Encode(
961        Data => \%Result,
962    );
963
964    return $LayoutObject->Attachment(
965        ContentType => 'application/json; charset=' . $LayoutObject->{Charset},
966        Content     => $JSON,
967        Type        => 'inline',
968        NoCache     => 1,
969    );
970}
971
9721;
973