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::System::SysConfig::BaseValueType;
10## nofilter(TidyAll::Plugin::OTRS::Perl::LayoutObject)
11
12use strict;
13use warnings;
14
15use Kernel::System::VariableCheck qw(:all);
16
17our @ObjectDependencies = (
18    'Kernel::Language',
19    'Kernel::Output::HTML::Layout',
20    'Kernel::System::Log',
21);
22
23=head1 NAME
24
25Kernel::System::SysConfig::BaseValueType - Common system configuration value type backend functions.
26
27=head1 PUBLIC INTERFACE
28
29=head2 SettingEffectiveValueCheck()
30
31Check if provided EffectiveValue matches structure defined in XMLContentParsed.
32
33    my %Result = $ValueTypeObject->SettingEffectiveValueCheck(
34        EffectiveValue => 'open',
35        XMLContentParsed => {
36            Value => [
37                {
38                    'Item' => [
39                        {
40                            'Content' => "Scalar value",
41                        },
42                    ],
43                },
44            ],
45        },
46    );
47
48Result:
49    $Result = (
50        EffectiveValue => 'open',    # Note for common ValueTypes EffectiveValue is not changed.
51        Success => 1,
52        Error   => undef,
53    );
54
55=cut
56
57sub SettingEffectiveValueCheck {
58    my ( $Self, %Param ) = @_;
59
60    for my $Needed (qw(XMLContentParsed)) {
61        if ( !$Param{$Needed} ) {
62            $Kernel::OM->Get('Kernel::System::Log')->Log(
63                Priority => 'error',
64                Message  => "Need $Needed!"
65            );
66
67            return;
68        }
69    }
70
71    my %Result = (
72        Success => 0,
73    );
74
75    my $Value = $Param{XMLContentParsed}->{Value};
76
77    for my $Parameter ( sort keys %{ $Param{Parameters} } ) {
78        if ( !defined $Value->[0]->{Item}->[0]->{$Parameter} ) {
79            $Value->[0]->{Item}->[0]->{$Parameter} = $Param{Parameters}->{$Parameter};
80        }
81    }
82
83    # Data should be scalar.
84    if ( ref $Param{EffectiveValue} ) {
85        $Result{Error} = 'EffectiveValue must be a scalar!';
86        return %Result;
87    }
88
89    my $Regex = $Value->[0]->{Item}->[0]->{ValueRegex};
90
91    # RegEx check - do not use any modifiers for compatibility reasons.
92    if ( $Regex && $Param{EffectiveValue} !~ m{$Regex} ) {
93        $Result{Error} = "EffectiveValue not valid - regex '$Regex'!";
94        return %Result;
95    }
96
97    $Result{Success}        = 1;
98    $Result{EffectiveValue} = $Param{EffectiveValue};
99
100    return %Result;
101}
102
103=head2 EffectiveValueGet()
104
105Extracts the effective value from a XML parsed setting.
106
107    my $EffectiveValue = $ValueTypeObject->EffectiveValueGet(
108        Value => [
109            {
110                ValueRegex => '',                       # (optional)
111                Content    => 'TheEffectiveValue',
112                ValueType  => 'AValueType',             # (optional)
113                # ...
114            }
115        ],
116    );
117
118Returns:
119
120    $EffectiveValue = 'TheEffectiveValue';
121
122=cut
123
124sub EffectiveValueGet {
125    my ( $Self, %Param ) = @_;
126
127    if ( !IsArrayRefWithData( $Param{Value} ) ) {
128        $Kernel::OM->Get('Kernel::System::Log')->Log(
129            Priority => 'error',
130            Message  => "Value is missing or invalid!",
131        );
132
133        return '';
134    }
135
136    if ( scalar @{ $Param{Value} } > 1 ) {
137        $Kernel::OM->Get('Kernel::System::Log')->Log(
138            Priority => 'error',
139            Message  => "Value must be a single element!",
140        );
141        return '';
142    }
143
144    $Param{Translate} = 0;    # common ValueTypes are never translated
145
146    my $Result = $Param{Value}->[0]->{Content} // '';
147
148    if (
149        $Result
150        && $Param{Translate}
151        && $Param{Value}->[0]->{Translatable}
152        )
153    {
154        $Result = $Kernel::OM->Get('Kernel::Language')->Translate($Result);
155    }
156
157    return $Result;
158}
159
160=head2 ModifiedValueGet()
161
162Returns parsed value with updated content(according to EffectiveValue).
163
164    my $ModifiedValue = $ValueTypeObject->ModifiedValueGet(
165        'EffectiveValue' => 'Item 1',
166        'Value' => [
167            {
168                'Item' => [
169                    {
170                        'Content' => 'Default value',
171                        'ValueType' => 'String',
172                    },
173                ],
174            },
175        ],
176    );
177
178Returns:
179
180    $ModifiedValue = [
181        {
182            'Item' => [
183                {
184                    'Content' => 'Item 1',
185                    'ValueType' => 'String',
186                },
187            ],
188        },
189    ];
190
191=cut
192
193sub ModifiedValueGet {
194    my ( $Self, %Param ) = @_;
195
196    for my $Needed (qw(Value)) {
197        if ( !$Param{$Needed} ) {
198            $Kernel::OM->Get('Kernel::System::Log')->Log(
199                Priority => 'error',
200                Message  => "Need $Needed!",
201            );
202            return;
203        }
204    }
205
206    my $Result = $Param{Value};
207
208    # Update Content
209    $Result->[0]->{Item}->[0]->{Content} = $Param{EffectiveValue} || '';
210
211    return $Result;
212}
213
214=head2 SettingRender()
215
216Extracts the effective value from a XML parsed setting.
217
218    my $SettingHTML = $ValueTypeObject->SettingRender(
219        Name           => 'SettingName',
220        EffectiveValue => 'Product 6',      # (optional)
221        DefaultValue   => 'Product 5',      # (optional)
222        Class          => 'My class'        # (optional)
223        Item           => [                 # (optional) XML parsed item
224            {
225                'ValueType' => 'String',
226                'Content' => 'admin@example.com',
227                'ValueRegex' => '',
228            },
229        ],
230        RW => 1,                            # (optional) Allow editing. Default 0.
231        IsArray  => 1,                      # (optional) Item is part of the array
232        IsHash   => 1,                      # (optional) Item is part of the hash
233        IDSuffix => 1,                      # (optional) Suffix will be added to the element ID
234        SkipEffectiveValueCheck => 1,       # (optional) If enabled, system will not perform effective value check.
235                                            #            Default: 1.
236    );
237
238Returns:
239
240    $SettingHTML = '<div class "Field"...</div>';
241
242=cut
243
244sub SettingRender {
245    my ( $Self, %Param ) = @_;
246
247    if ( !defined $Param{Name} ) {
248        $Kernel::OM->Get('Kernel::System::Log')->Log(
249            Priority => 'error',
250            Message  => "Need Name",
251        );
252        return;
253    }
254
255    $Param{EffectiveValue} //= '';
256    $Param{Class}          //= '';
257    $Param{DefaultValue}   //= '';
258    my $IDSuffix = $Param{IDSuffix} || '';
259
260    my $LanguageObject = $Kernel::OM->Get('Kernel::Language');
261
262    my $EffectiveValue = $Param{EffectiveValue};
263    if (
264        !defined $EffectiveValue
265        && $Param{Item}
266        && $Param{Item}->[0]->{Content}
267        )
268    {
269        $EffectiveValue = $Param{Item}->[0]->{Content};
270    }
271
272    my $Regex;
273    if ( $Param{Item}->[0]->{ValueRegex} ) {
274        $Regex = $Param{Item}->[0]->{ValueRegex};
275        $Param{Class} .= ' Validate_Regex ';
276    }
277
278    my $DefaultValueStrg = $LanguageObject->Translate('Default');
279
280    my %EffectiveValueCheck = (
281        Success => 1,
282    );
283
284    if ( !$Param{SkipEffectiveValueCheck} ) {
285        %EffectiveValueCheck = $Self->SettingEffectiveValueCheck(
286            EffectiveValue   => $EffectiveValue,
287            XMLContentParsed => {
288                Value => [
289                    {
290                        Item => $Param{Item},
291                    },
292                ],
293            },
294        );
295    }
296
297    my $HTML = '<div class="SettingContent">';
298    $HTML .= "<input class=\"$Param{Class}\" type=\"text\" name=\"$Param{Name}\" id=\"$Param{Name}$IDSuffix\" ";
299
300    my $HTMLValue = $Kernel::OM->Get('Kernel::Output::HTML::Layout')->Ascii2Html(
301        Text => $EffectiveValue,
302        Type => 'Normal',
303    );
304    $HTML .= "value=\"$HTMLValue\" ";
305
306    if ($Regex) {
307        $HTML .= "data-regex=\"$Regex\" ";
308    }
309
310    if ( !$Param{RW} ) {
311        $HTML .= "disabled='disabled' ";
312    }
313
314    $HTML .= " />\n";
315
316    if ( !$EffectiveValueCheck{Success} ) {
317        my $Message = $LanguageObject->Translate("Value is not correct! Please, consider updating this field.");
318
319        $HTML .= $Param{IsValid} ? "<div class='BadEffectiveValue'>\n" : "<div>\n";
320        $HTML .= "<p>* $Message</p>\n";
321        $HTML .= "</div>\n";
322    }
323
324    if ($Regex) {
325        my $Message = $LanguageObject->Translate(
326            "Value doesn't satisfy regex (%s).", $Regex,
327        );
328
329        $HTML .= "<div class='TooltipErrorMessage' id=\"$Param{Name}$IDSuffix" . "Error\">\n";
330        $HTML .= "<p>$Message</p>\n";
331        $HTML .= "</div>\n";
332    }
333
334    $HTML .= "</div>";
335
336    if ( !$Param{IsArray} && !$Param{IsHash} ) {
337        $HTML .= <<"EOF";
338                                <div class=\"WidgetMessage Bottom\">
339                                    $DefaultValueStrg: $Param{DefaultValue}
340                                </div>
341EOF
342    }
343
344    return $HTML;
345}
346
347sub EffectiveValueCalculate {
348    my ( $Self, %Param ) = @_;
349
350    # Check needed stuff.
351    for my $Needed (qw(Name)) {
352        if ( !$Param{$Needed} ) {
353            $Kernel::OM->Get('Kernel::System::Log')->Log(
354                Priority => 'error',
355                Message  => "Need $Needed!",
356            );
357            return;
358        }
359    }
360
361    my $Result = '';
362
363    if ( $Param{ $Param{Name} } ) {
364        $Result = $Param{ $Param{Name} };
365    }
366
367    return $Result;
368}
369
370=head2 AddItem()
371
372Generate HTML for new array/hash item.
373
374    my $HTML = $ValueTypeObject->AddItem(
375        Name           => 'SettingName',    (required) Name
376        DefaultItem    => {                 (optional) DefaultItem hash, if available
377            Item => {
378                Content => 'Value',
379            },
380        },
381    );
382
383Returns:
384
385    $HTML = "<input type='text' id='Setting_ExampleArray'
386        value='Value' name='ExampleArray' class='Entry'/>";
387
388=cut
389
390sub AddItem {
391    my ( $Self, %Param ) = @_;
392
393    # Check needed stuff.
394    for my $Needed (qw(Name)) {
395        if ( !$Param{$Needed} ) {
396            $Kernel::OM->Get('Kernel::System::Log')->Log(
397                Priority => 'error',
398                Message  => "Need $Needed!",
399            );
400            return;
401        }
402    }
403
404    my $IDSuffix = $Param{IDSuffix} || '';
405    my $Class    = $Param{Class}    || '';
406
407    my $Name = $Param{Name} . $IDSuffix;
408
409    my $DefaultValue = '';
410
411    if ( $Param{DefaultItem} && $Param{DefaultItem}->{Item} ) {
412        $DefaultValue = $Param{DefaultItem} && $Param{DefaultItem}->{Item}->{Content} || '';
413    }
414    elsif ( $Param{DefaultItem} ) {
415        $DefaultValue = $Param{DefaultItem} && $Param{DefaultItem}->{Content} || '';
416    }
417
418    my $RemoveThisEntry = $Kernel::OM->Get('Kernel::Language')->Translate("Remove this entry");
419
420    my $Result = "<input type='text' id='$Name'
421        value='$DefaultValue' name='$Param{Name}' class='$Class Entry'/>";
422
423    return $Result;
424}
425
426=head2 ValueAttributeGet()
427
428Returns attribute name in the parsed XML that contains Value.
429
430    my $Result = $ValueTypeObject->ValueAttributeGet();
431
432Result:
433    $Result = 'Content';
434
435=cut
436
437sub ValueAttributeGet {
438    my ( $Self, %Param ) = @_;
439
440    return 'Content';
441}
442
443=head2 DefaultItemAdd()
444
445Return structure of the DefaultItem in case it's not inside of Array or Hash.
446
447    my $DefaultItem = $ValueTypeObject->DefaultItemAdd();
448
449Returns:
450
451    $DefaultItem = undef;
452        # or
453    $DefaultItem = {
454        Item => {
455            Content => '',
456        },
457        ValueType => 'VacationDaysOneTime',
458    };
459
460=cut
461
462sub DefaultItemAdd {
463    my ( $Self, %Param ) = @_;
464
465    # For most ValueTypes there is no such case, so return undef.
466    return;
467}
468
469=head2 ForbiddenValueTypes()
470
471Return array of value types that are not allowed inside this value type.
472
473    my @ForbiddenValueTypes = $ValueTypeObject->ForbiddenValueTypes();
474
475Returns:
476
477    @ForbiddenValueTypes = (
478        'Option',
479        ...
480    );
481
482=cut
483
484sub ForbiddenValueTypes {
485    my ( $Self, %Param ) = @_;
486
487    return ();
488}
489
490=head2 AddSettingContent()
491
492Checks if a div with class 'SettingContent' should be added when adding new item to an array/hash in some special cases.
493
494    my $AddSettingContent = $ValueTypeObject->AddSettingContent();
495
496Returns:
497
498    my $AddSettingContent = 1;
499
500=cut
501
502sub AddSettingContent {
503    my ( $Self, %Param ) = @_;
504
505    return 1;
506}
507
5081;
509