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## nofilter(TidyAll::Plugin::OTRS::Perl::LayoutObject)
9
10package Kernel::System::SysConfig::ValueType::FrontendRegistration;
11
12use strict;
13use warnings;
14
15use Kernel::System::VariableCheck qw(:all);
16
17use parent qw(Kernel::System::SysConfig::BaseValueType);
18
19our @ObjectDependencies = (
20    'Kernel::Language',
21    'Kernel::Output::HTML::Layout',
22    'Kernel::System::Log',
23);
24
25=head1 NAME
26
27Kernel::System::SysConfig::ValueType::FrontendRegistration - System configuration frontend registration value type backed.
28
29=head1 PUBLIC INTERFACE
30
31=head2 new()
32
33Create an object. Do not use it directly, instead use:
34
35    use Kernel::System::ObjectManager;
36    local $Kernel::OM = Kernel::System::ObjectManager->new();
37    my $ValueTypeObject = $Kernel::OM->Get('Kernel::System::SysConfig::ValueType::FrontendRegistration');
38
39=cut
40
41sub new {
42    my ( $Type, %Param ) = @_;
43
44    # Allocate new hash for object.
45    my $Self = {};
46    bless( $Self, $Type );
47
48    return $Self;
49}
50
51=head2 SettingEffectiveValueCheck()
52
53Check if provided EffectiveValue matches structure defined in XMLContentParsed.
54
55    my %Result = $ValueTypeObject->SettingEffectiveValueCheck(
56        XMLContentParsed => {
57            Value => [
58                {
59                    'Item' => [
60                        {
61                            ...
62                        },
63                    ],
64                },
65            ],
66        },
67        EffectiveValue => {
68            ...
69        },
70    );
71
72Result:
73    %Result = (
74        EffectiveValue => {         # Note for FrontendRegistration ValueTypes EffectiveValue is not changed.
75            ...
76        },
77        Success => 1,
78        Error   => undef,
79    );
80
81=cut
82
83sub SettingEffectiveValueCheck {
84    my ( $Self, %Param ) = @_;
85
86    for my $Needed (qw(XMLContentParsed)) {
87        if ( !$Param{$Needed} ) {
88            $Kernel::OM->Get('Kernel::System::Log')->Log(
89                Priority => 'error',
90                Message  => "Need $Needed!"
91            );
92
93            return;
94        }
95    }
96
97    my %Result = (
98        Success => 0,
99    );
100
101    if ( !IsHashRefWithData( $Param{EffectiveValue} ) ) {
102        $Result{Error} = "FrontendRegistration EffectiveValue must be a hash!";
103        return %Result;
104    }
105
106    DEFINED:
107    for my $Defined (qw(NavBarName Description)) {
108        if ( !defined $Param{EffectiveValue}->{$Defined} ) {
109            $Result{Error} = "FrontendRegistration must define $Defined!";
110            last DEFINED;
111        }
112    }
113
114    return %Result if $Result{Error};
115
116    $Result{Success}        = 1;
117    $Result{EffectiveValue} = $Param{EffectiveValue};
118
119    return %Result;
120}
121
122=head2 EffectiveValueGet()
123
124Extracts the effective value from a XML parsed setting.
125
126    my $EffectiveValue = $ValueTypeObject->EffectiveValueGet(
127        Value => [
128            {
129                ValueRegex => '',                       # optional
130                Content    => 'TheEffectiveValue',
131                ValueType  => 'AValueType',             # optional
132                # ...
133            }
134        ],
135    );
136
137Returns:
138
139    $EffectiveValue = 'TheEffectiveValue';
140
141=cut
142
143sub EffectiveValueGet {
144    my ( $Self, %Param ) = @_;
145
146    if ( !IsArrayRefWithData( $Param{Value} ) ) {
147        $Kernel::OM->Get('Kernel::System::Log')->Log(
148            Priority => 'error',
149            Message  => "Value is missing or invalid!",
150        );
151
152        return '';
153    }
154
155    if ( scalar @{ $Param{Value} } > 1 ) {
156        $Kernel::OM->Get('Kernel::System::Log')->Log(
157            Priority => 'error',
158            Message  => "Value must be a single element!",
159        );
160        return '';
161    }
162
163    return if ( !$Param{Value}->[0]->{Hash} );
164    return if ( !$Param{Value}->[0]->{Hash}->[0] );
165    return if ( !$Param{Value}->[0]->{Hash}->[0]->{Item} );
166
167    my $EffectiveValue;
168
169    for my $Item ( @{ $Param{Value}->[0]->{Hash}->[0]->{Item} } ) {
170
171        if ( grep { $Item->{Key} eq $_ } qw(Group GroupRo) ) {
172
173            # contains array
174
175            if ( $Item->{Array} ) {
176                my @Array = ();
177
178                if (
179                    $Item->{Array}
180                    && $Item->{Array}->[0]->{Item}
181                    )
182                {
183                    for my $ArrayItem ( @{ $Item->{Array}->[0]->{Item} } ) {
184                        push @Array, $ArrayItem->{Content} || '';
185                    }
186                }
187                $EffectiveValue->{ $Item->{Key} } = \@Array;
188            }
189        }
190        else {
191            # contains value
192            $EffectiveValue->{ $Item->{Key} } = $Item->{Content} || '';
193        }
194    }
195
196    # Set undefined group attributes.
197    for my $Group (qw(Group GroupRo)) {
198        if ( !defined $EffectiveValue->{$Group} ) {
199            $EffectiveValue->{$Group} = [];
200        }
201    }
202
203    return $EffectiveValue;
204}
205
206=head2 SettingRender()
207
208Extracts the effective value from a XML parsed setting.
209
210    my $SettingHTML = $ValueTypeObject->SettingRender(
211        Name           => 'SettingName',
212        DefaultID      =>  123,             # (required)
213        EffectiveValue => '2016-02-02',
214        DefaultValue   => 'Product 5',      # (optional)
215        Class          => 'My class'        # (optional)
216        RW             => 1,                # (optional) Allow editing. Default 0.
217        Item           => [                 # (optional) XML parsed item
218            {
219                'ValueType' => 'FrontendRegistration',
220                'Content' => '2016-02-02',
221                'ValueRegex' => '',
222            },
223        ],
224        IsArray  => 1,                      # (optional) Item is part of the array
225        IsHash   => 1,                      # (optional) Item is part of the hash
226        IDSuffix => 1,                      # (optional) Suffix will be added to the element ID
227        SkipEffectiveValueCheck => 1,       # (optional) If enabled, system will not perform effective value check.
228                                            #            Default: 1.
229    );
230
231Returns:
232
233    $SettingHTML = '<div class "Field"...</div>';
234
235=cut
236
237sub SettingRender {
238    my ( $Self, %Param ) = @_;
239
240    for my $Needed (qw(Name EffectiveValue)) {
241        if ( !defined $Param{$Needed} ) {
242            $Kernel::OM->Get('Kernel::System::Log')->Log(
243                Priority => 'error',
244                Message  => "Need $Needed",
245            );
246            return;
247        }
248    }
249
250    $Param{Class}        //= '';
251    $Param{DefaultValue} //= '';
252    $Param{IDSuffix}     //= '';
253
254    my $LanguageObject = $Kernel::OM->Get('Kernel::Language');
255    my $LayoutObject   = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
256
257    my $EffectiveValue = $Param{EffectiveValue};
258
259    if ( !IsHashRefWithData($EffectiveValue) ) {
260        $Kernel::OM->Get('Kernel::System::Log')->Log(
261            Priority => 'error',
262            Message  => "EffectiveValue must be a hash!"
263        );
264        return '';
265    }
266
267    # Set undefined group attributes.
268    for my $Group (qw(Group GroupRo)) {
269        if ( !defined $EffectiveValue->{$Group} ) {
270            $EffectiveValue->{$Group} = [];
271        }
272    }
273
274    my %EffectiveValueCheck = (
275        Success => 1,
276    );
277
278    if ( !$Param{SkipEffectiveValueCheck} ) {
279        %EffectiveValueCheck = $Self->SettingEffectiveValueCheck(
280            EffectiveValue   => $EffectiveValue,
281            XMLContentParsed => {
282                Value => [
283                    {
284                        Item => $Param{Item},
285                    },
286                ],
287            },
288        );
289    }
290
291    my $HTML = "<div class='Hash'>\n";
292
293    if ( !$EffectiveValueCheck{Success} ) {
294        my $Message = $LanguageObject->Translate("Value is not correct! Please, consider updating this module.");
295
296        $HTML .= $Param{IsValid} ? "<div class='BadEffectiveValue'>\n" : "<div>\n";
297        $HTML .= "<p>* $Message</p>\n";
298        $HTML .= "</div>\n";
299    }
300
301    my $AddNewEntry     = $LanguageObject->Translate("Add new entry");
302    my $RemoveThisEntry = $LanguageObject->Translate("Remove this entry");
303
304    if ( !defined $EffectiveValue->{Title} ) {
305        $EffectiveValue->{Title} = '';
306    }
307
308    my $Readonly = '';
309    if ( !$Param{RW} ) {
310        $Readonly = "readonly='readonly'";
311    }
312
313    for my $Key ( sort keys %{$EffectiveValue} ) {
314
315        $HTML .= "<div class='HashItem'>\n";
316        $HTML .= "<input type='text' value='$Key' readonly='readonly' class='Key' />\n";
317
318        $HTML .= "<div class='SettingContent'>\n";
319
320        if ( grep { $Key eq $_ } qw (Group GroupRo) ) {
321            $HTML .= "<div class='Array'>\n";
322
323            my $GroupIndex = 1;
324            for my $GroupItem ( @{ $EffectiveValue->{$Key} } ) {
325
326                my $HTMLGroupItem = $LayoutObject->Ascii2Html(
327                    Text => $GroupItem,
328                    Type => 'Normal',
329                );
330
331                $HTML .= "<div class='ArrayItem'>\n";
332                $HTML .= "<div class='SettingContent'>\n";
333                $HTML .= "<input type='text' value='$HTMLGroupItem' "
334                    . "id='$Param{Name}_Hash###$Key\_Array$GroupIndex' $Readonly />\n";
335                $HTML .= "</div>\n";
336
337                if ( $Param{RW} ) {
338                    $HTML .= "<button class='RemoveButton' type='button' "
339                        . "title='$RemoveThisEntry' value='Remove this entry'>\n"
340                        . "    <i class='fa fa-minus-circle'></i>\n"
341                        . "    <span class='InvisibleText'>$RemoveThisEntry</span>\n"
342                        . "</button>\n";
343                }
344
345                $HTML .= "</div>\n";
346
347                $GroupIndex++;
348            }
349
350            my $ButtonClass = 'AddArrayItem';
351            if ( !$Param{RW} ) {
352                $ButtonClass .= " Hidden";
353            }
354
355            # Always add "AddArrayItem" button, it might be needed when calculating effective value (if array is empty).
356            $HTML .= "    <button data-suffix='$Param{Name}_Hash###$Key\_Array$GroupIndex' class='$ButtonClass' "
357                . "type='button' title='$AddNewEntry' value='Add new entry'>\n"
358                . "        <i class='fa fa-plus-circle'></i>\n"
359                . "        <span class='InvisibleText'>$AddNewEntry</span>\n"
360                . "    </button>\n";
361
362            $HTML .= "</div>\n";
363        }
364        else {
365            my $HTMLValue = $LayoutObject->Ascii2Html(
366                Text => $EffectiveValue->{$Key},
367                Type => 'Normal',
368            );
369
370            $HTML .= "<input type='text' value='$HTMLValue' "
371                . "id='$Param{Name}_Hash###$Key' $Readonly />\n";
372        }
373
374        $HTML .= "</div>\n";
375        $HTML .= "</div>\n";
376    }
377    $HTML .= "</div>\n";
378
379    return $HTML;
380}
381
3821;
383
384=head1 TERMS AND CONDITIONS
385
386This software is part of the OTRS project (L<https://otrs.org/>).
387
388This software comes with ABSOLUTELY NO WARRANTY. For details, see
389the enclosed file COPYING for license information (GPL). If you
390did not receive this file, see L<https://www.gnu.org/licenses/gpl-3.0.txt>.
391
392=cut
393