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::DynamicField::Backend;
10
11use strict;
12use warnings;
13
14use Scalar::Util qw(weaken);
15
16use Kernel::System::VariableCheck qw(:all);
17
18our @ObjectDependencies = (
19    'Kernel::Config',
20    'Kernel::System::DB',
21    'Kernel::System::DynamicField',
22    'Kernel::System::DynamicFieldValue',
23    'Kernel::System::Log',
24    'Kernel::System::Main',
25);
26
27=head1 NAME
28
29Kernel::System::DynamicField::Backend
30
31=head1 DESCRIPTION
32
33DynamicFields backend interface
34
35=head1 PUBLIC INTERFACE
36
37=head2 new()
38
39create a DynamicField backend object. Do not use it directly, instead use:
40
41    my $BackendObject = $Kernel::OM->Get('Kernel::System::DynamicField::Backend');
42
43=cut
44
45sub new {
46    my ( $Type, %Param ) = @_;
47
48    # allocate new hash for object
49    my $Self = {};
50    bless( $Self, $Type );
51
52    # get config object
53    my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
54
55    # get the Dynamic Field Backends configuration
56    my $DynamicFieldsConfig = $ConfigObject->Get('DynamicFields::Driver');
57
58    # check Configuration format
59    if ( !IsHashRefWithData($DynamicFieldsConfig) ) {
60        $Kernel::OM->Get('Kernel::System::Log')->Log(
61            Priority => 'error',
62            Message  => "Dynamic field configuration is not valid!",
63        );
64        return;
65    }
66
67    # get main object
68    my $MainObject = $Kernel::OM->Get('Kernel::System::Main');
69
70    # create all registered backend modules
71    for my $FieldType ( sort keys %{$DynamicFieldsConfig} ) {
72
73        # check if the registration for each field type is valid
74        if ( !$DynamicFieldsConfig->{$FieldType}->{Module} ) {
75            $Kernel::OM->Get('Kernel::System::Log')->Log(
76                Priority => 'error',
77                Message  => "Registration for field type $FieldType is invalid!",
78            );
79            return;
80        }
81
82        # set the backend file
83        my $BackendModule = $DynamicFieldsConfig->{$FieldType}->{Module};
84
85        # check if backend field exists
86        if ( !$MainObject->Require($BackendModule) ) {
87            $Kernel::OM->Get('Kernel::System::Log')->Log(
88                Priority => 'error',
89                Message  => "Can't load dynamic field backend module for field type $FieldType!",
90            );
91            return;
92        }
93
94        # create a backend object
95        my $BackendObject = $BackendModule->new( %{$Self} );
96
97        if ( !$BackendObject ) {
98            $Kernel::OM->Get('Kernel::System::Log')->Log(
99                Priority => 'error',
100                Message  => "Couldn't create a backend object for field type $FieldType!",
101            );
102            return;
103        }
104
105        if ( ref $BackendObject ne $BackendModule ) {
106            $Kernel::OM->Get('Kernel::System::Log')->Log(
107                Priority => 'error',
108                Message  => "Backend object for field type $FieldType was not created successfuly!",
109            );
110            return;
111        }
112
113        # remember the backend object
114        $Self->{ 'DynamicField' . $FieldType . 'Object' } = $BackendObject;
115    }
116
117    # get the Dynamic Field Objects configuration
118    my $DynamicFieldObjectTypeConfig = $ConfigObject->Get('DynamicFields::ObjectType');
119
120    # check Configuration format
121    if ( IsHashRefWithData($DynamicFieldObjectTypeConfig) ) {
122
123        # create all registered ObjectType handler modules
124        for my $ObjectType ( sort keys %{$DynamicFieldObjectTypeConfig} ) {
125
126            # check if the registration for each field type is valid
127            if ( !$DynamicFieldObjectTypeConfig->{$ObjectType}->{Module} ) {
128                $Kernel::OM->Get('Kernel::System::Log')->Log(
129                    Priority => 'error',
130                    Message  => "Registration for object type $ObjectType is invalid!",
131                );
132                return;
133            }
134
135            # set the backend file
136            my $ObjectHandlerModule = $DynamicFieldObjectTypeConfig->{$ObjectType}->{Module};
137
138            # check if backend field exists
139            if ( !$MainObject->Require($ObjectHandlerModule) ) {
140                $Kernel::OM->Get('Kernel::System::Log')->Log(
141                    Priority => 'error',
142                    Message =>
143                        "Can't load dynamic field object handler module for object type $ObjectType!",
144                );
145                return;
146            }
147
148            # create a backend object
149            my $ObjectHandlerObject = $ObjectHandlerModule->new(
150                %{$Self},
151                %Param,    # pass %Param too, for optional arguments like TicketObject
152            );
153
154            if ( !$ObjectHandlerObject ) {
155                $Kernel::OM->Get('Kernel::System::Log')->Log(
156                    Priority => 'error',
157                    Message  => "Couldn't create a handler object for object type $ObjectType!",
158                );
159                return;
160            }
161
162            if ( ref $ObjectHandlerObject ne $ObjectHandlerModule ) {
163                $Kernel::OM->Get('Kernel::System::Log')->Log(
164                    Priority => 'error',
165                    Message =>
166                        "Handler object for object type $ObjectType was not created successfuly!",
167                );
168                return;
169            }
170
171            # remember the backend object
172            $Self->{ 'DynamicField' . $ObjectType . 'HandlerObject' } = $ObjectHandlerObject;
173        }
174    }
175
176    # get the Dynamic Field Backend custmom extensions
177    my $DynamicFieldBackendExtensions = $ConfigObject->Get('DynamicFields::Extension::Backend');
178
179    EXTENSION:
180    for my $ExtensionKey ( sort keys %{$DynamicFieldBackendExtensions} ) {
181
182        # skip invalid extensions
183        next EXTENSION if !IsHashRefWithData( $DynamicFieldBackendExtensions->{$ExtensionKey} );
184
185        # create a extension config shortcut
186        my $Extension = $DynamicFieldBackendExtensions->{$ExtensionKey};
187
188        # skip if extension does not contain a backend module
189        next EXTENSION if !$Extension->{Module};
190
191        # check if module can be loaded
192        if ( !$MainObject->RequireBaseClass( $Extension->{Module} ) ) {
193            die "Can't load dynamic fields backend module $Extension->{Backend}! $@";
194        }
195    }
196
197    return $Self;
198}
199
200=head2 EditFieldRender()
201
202creates the field HTML to be used in edit masks.
203
204    my $FieldHTML = $BackendObject->EditFieldRender(
205        DynamicFieldConfig   => $DynamicFieldConfig,      # complete config of the DynamicField
206        ParamObject          => $ParamObject,
207        LayoutObject         => $LayoutObject,
208        PossibleValuesFilter => {                         # Optional. Some backends may support this.
209            'Key1' => 'Value1',                           #     This may be needed to realize ACL support for ticket masks,
210            'Key2' => 'Value2',                           #     where the possible values can be limited with and ACL.
211        },
212        Template             => {                         # Optional data structure of GenericAgent etc.
213            Owner => 2,                                   # Value is accessable via field name (DynamicField_ + field name)
214            Title => 'Generic Agent Job was here'         # and could be a scalar, Hash- or ArrayRef
215            ...
216            DynamicField_ExampleField1 => 'Value 1'
217        },
218        Value                => 'Any value',              # Optional
219        Mandatory            => 1,                        # 0 or 1,
220        Class                => 'AnyCSSClass OrOneMore',  # Optional
221        ServerError          => 1,                        # 0 or 1,
222        ErrorMessage         => $ErrorMessage,            # Optional or a default will be used in error case
223        UseDefaultValue      => 1,                        # 0 or 1, 1 default
224        OverridePossibleNone => 1,                        # Optional, 0 or 1. If defined orverrides the Possible None
225                                                          #     setting of all dynamic fields (where applies) with the
226                                                          #     defined value
227        ConfirmationNeeded   => 0,                        # Optional, 0 or 1, default 0. To display a confirmation element
228                                                          #     on fields that apply (like checkbox)
229        AJAXUpdate           => 1,                        # Optional, 0 ir 1. To create JS code for field change to update
230                                                          #     the form using ACLs triggered by the field.
231        UpdatableFields      => [                         # Optional, to use if AJAXUpdate is 1. List of fields to display a
232            'NetxStateID',                                #     spinning wheel when reloading via AJAXUpdate.
233            'PriorityID',
234        ],
235        MaxLength            => 100                       # Optional, defines the maximum number of characters on fields
236                                                          #      where applies (like TextArea)
237    );
238
239    Returns {
240        Field => $HTMLString,
241        Label => $LabelString,
242    };
243
244=cut
245
246sub EditFieldRender {
247    my ( $Self, %Param ) = @_;
248
249    # check needed stuff
250    for my $Needed (qw(DynamicFieldConfig LayoutObject ParamObject)) {
251        if ( !$Param{$Needed} ) {
252            $Kernel::OM->Get('Kernel::System::Log')->Log(
253                Priority => 'error',
254                Message  => "Need $Needed!"
255            );
256            return;
257        }
258    }
259
260    # check DynamicFieldConfig (general)
261    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
262        $Kernel::OM->Get('Kernel::System::Log')->Log(
263            Priority => 'error',
264            Message  => "The field configuration is invalid",
265        );
266        return;
267    }
268
269    # check DynamicFieldConfig (internally)
270    for my $Needed (qw(ID FieldType ObjectType Config Name)) {
271        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
272            $Kernel::OM->Get('Kernel::System::Log')->Log(
273                Priority => 'error',
274                Message  => "Need $Needed in DynamicFieldConfig!"
275            );
276            return;
277        }
278    }
279
280    # check PossibleValuesFilter (general)
281    if (
282        defined $Param{PossibleValuesFilter}
283        && ref $Param{PossibleValuesFilter} ne 'HASH'
284        )
285    {
286        $Kernel::OM->Get('Kernel::System::Log')->Log(
287            Priority => 'error',
288            Message  => "The possible values filter is invalid",
289        );
290        return;
291    }
292
293    # set the dynamic field specific backend
294    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
295
296    if ( !$Self->{$DynamicFieldBackend} ) {
297        $Kernel::OM->Get('Kernel::System::Log')->Log(
298            Priority => 'error',
299            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
300        );
301        return;
302    }
303
304    # set use default value as default if not specified
305    if ( !defined $Param{UseDefaultValue} ) {
306        $Param{UseDefaultValue} = 1;
307    }
308
309    # call EditFieldRender on the specific backend
310    my $HTMLStrings = $Self->{$DynamicFieldBackend}->EditFieldRender(%Param);
311
312    return $HTMLStrings;
313
314}
315
316=head2 DisplayValueRender()
317
318creates value and title strings to be used in display masks. Supports HTML output
319and will transform dates to the current user's timezone.
320
321    my $ValueStrg = $BackendObject->DisplayValueRender(
322        DynamicFieldConfig => $DynamicFieldConfig,      # complete config of the DynamicField
323        Value              => 'Any value',              # Optional
324        HTMLOutput         => 1,                        # or 0, default 1, to return HTML ready
325                                                        #    values
326        ValueMaxChars      => 20,                       # Optional (for HTMLOutput only)
327        TitleMaxChars      => 20,                       # Optional (for HTMLOutput only)
328        LayoutObject       => $LayoutObject,
329    );
330
331    Returns
332
333    $ValueStrg = {
334        Title       => $Title,
335        Value       => $Value,
336        Link        => $Link,
337        LinkPreview => $LinkPreview,
338    }
339
340=cut
341
342sub DisplayValueRender {
343    my ( $Self, %Param ) = @_;
344
345    # check needed stuff
346    for my $Needed (qw(DynamicFieldConfig LayoutObject)) {
347        if ( !$Param{$Needed} ) {
348            $Kernel::OM->Get('Kernel::System::Log')->Log(
349                Priority => 'error',
350                Message  => "Need $Needed!"
351            );
352            return;
353        }
354    }
355
356    # check DynamicFieldConfig (general)
357    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
358        $Kernel::OM->Get('Kernel::System::Log')->Log(
359            Priority => 'error',
360            Message  => "The field configuration is invalid",
361        );
362        return;
363    }
364
365    # check DynamicFieldConfig (internally)
366    for my $Needed (qw(ID FieldType ObjectType Config Name)) {
367        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
368            $Kernel::OM->Get('Kernel::System::Log')->Log(
369                Priority => 'error',
370                Message  => "Need $Needed in DynamicFieldConfig!"
371            );
372            return;
373        }
374    }
375
376    # set the dynamic field specific backend
377    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
378
379    if ( !$Self->{$DynamicFieldBackend} ) {
380        $Kernel::OM->Get('Kernel::System::Log')->Log(
381            Priority => 'error',
382            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
383        );
384        return;
385    }
386
387    # call DisplayValueRender on the specific backend
388    my $ValueStrg = $Self->{$DynamicFieldBackend}->DisplayValueRender(%Param);
389
390    return $ValueStrg;
391}
392
393=head2 ValueSet()
394
395sets a dynamic field value.
396
397    my $Success = $BackendObject->ValueSet(
398        DynamicFieldConfig => $DynamicFieldConfig,      # complete config of the DynamicField
399        ObjectID           => $ObjectID,                # ID of the current object that the field
400                                                        # must be linked to, e. g. TicketID
401        ObjectName         => $ObjectName,              # Name of the current object that the field
402                                                        # must be linked to, e. g. CustomerUserLogin
403                                                        # You have to give either ObjectID OR ObjectName
404        Value              => $Value,                   # Value to store, depends on backend type
405        UserID             => 123,
406    );
407
408=cut
409
410sub ValueSet {
411    my ( $Self, %Param ) = @_;
412
413    # check needed stuff
414    for my $Needed (qw(DynamicFieldConfig UserID)) {
415        if ( !$Param{$Needed} ) {
416            $Kernel::OM->Get('Kernel::System::Log')->Log(
417                Priority => 'error',
418                Message  => "Need $Needed!"
419            );
420            return;
421        }
422    }
423
424    # Either ObjectID or ObjectName has to be given
425    if (
426        ( !$Param{ObjectID} && !$Param{ObjectName} )
427        || ( $Param{ObjectID} && $Param{ObjectName} )
428        )
429    {
430        $Kernel::OM->Get('Kernel::System::Log')->Log(
431            Priority => 'error',
432            Message  => "Either ObjectID or ObjectName hast to be given!"
433        );
434        return;
435    }
436
437    # check DynamicFieldConfig (general)
438    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
439        $Kernel::OM->Get('Kernel::System::Log')->Log(
440            Priority => 'error',
441            Message  => "The field configuration is invalid",
442        );
443        return;
444    }
445
446    # If ObjectName has been given, fetch/create an ID for it
447    if ( $Param{ObjectName} ) {
448        my $ObjectIDs = $Kernel::OM->Get('Kernel::System::DynamicField')->ObjectMappingGet(
449            ObjectName => $Param{ObjectName},
450            ObjectType => $Param{DynamicFieldConfig}->{ObjectType},
451        );
452
453        if ( IsHashRefWithData($ObjectIDs) && $ObjectIDs->{ $Param{ObjectName} } ) {
454            $Param{ObjectID} = $ObjectIDs->{ $Param{ObjectName} };
455        }
456        else {
457            my $ObjectID = $Kernel::OM->Get('Kernel::System::DynamicField')->ObjectMappingCreate(
458                ObjectName => $Param{ObjectName},
459                ObjectType => $Param{DynamicFieldConfig}->{ObjectType},
460            );
461
462            if ( !$ObjectID ) {
463                $Kernel::OM->Get('Kernel::System::Log')->Log(
464                    Priority => 'error',
465                    Message =>
466                        "Unable to create object mapping for object name $Param{ObjectName} and type $Param{DynamicFieldConfig}->{ObjectType}!"
467                );
468                return;
469            }
470
471            $Param{ObjectID} = $ObjectID;
472        }
473    }
474
475    # check DynamicFieldConfig (internally)
476    for my $Needed (qw(ID FieldType ObjectType)) {
477        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
478            $Kernel::OM->Get('Kernel::System::Log')->Log(
479                Priority => 'error',
480                Message  => "Need $Needed in DynamicFieldConfig!"
481            );
482            return;
483        }
484    }
485
486    # set the dynamic field specific backend
487    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
488
489    if ( !$Self->{$DynamicFieldBackend} ) {
490        $Kernel::OM->Get('Kernel::System::Log')->Log(
491            Priority => 'error',
492            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
493        );
494        return;
495    }
496
497    my $OldValue = $Self->ValueGet(
498        DynamicFieldConfig => $Param{DynamicFieldConfig},
499        ObjectID           => $Param{ObjectID},
500    );
501
502    my $NewValue = $Param{Value};
503
504    # do not proceed if there is nothing to update, each dynamic field requires special handling to
505    #    determine if two values are different or not, this to prevent false update events,
506    #    see bug #9828. Note: (do not send %Param, as $NewValue is a reference and then Value2 could
507    #    have strange values).
508    if (
509        !$Self->ValueIsDifferent(
510            DynamicFieldConfig => $Param{DynamicFieldConfig},
511            Value1             => $OldValue,
512            Value2             => $NewValue,
513        )
514        )
515    {
516        return 1;
517    }
518
519    # call ValueSet on the specific backend
520    my $Success = $Self->{$DynamicFieldBackend}->ValueSet(%Param);
521
522    if ( !$Success ) {
523        $Kernel::OM->Get('Kernel::System::Log')->Log(
524            Priority => 'error',
525            Message  => "Could not update field $Param{DynamicFieldConfig}->{Name} for "
526                . "$Param{DynamicFieldConfig}->{ObjectType} ID $Param{ObjectID} !",
527        );
528        return;
529    }
530
531    # set the dyanamic field object handler
532    my $DynamicFieldObjectHandler =
533        'DynamicField' . $Param{DynamicFieldConfig}->{ObjectType} . 'HandlerObject';
534
535    # If an ObjectType handler is registered, use it.
536    if ( ref $Self->{$DynamicFieldObjectHandler} ) {
537        return $Self->{$DynamicFieldObjectHandler}->PostValueSet(
538            OldValue => $OldValue,
539            %Param,
540        );
541    }
542
543    return 1;
544}
545
546=head2 ValueIsDifferent()
547
548compares if two dynamic field values are different.
549
550This function relies on Kernel::System::VariableCheck::DataIsDifferent() but with some exceptions
551depending on each field.
552
553    my $Success = $BackendObject->ValueIsDifferent(
554        DynamicFieldConfig => $DynamicFieldConfig,      # complete config of the DynamicField
555                                                        # must be linked to, e. g. TicketID
556        Value1             => $Value1,                  # Dynamic Field Value
557        Value2             => $Value2,                  # Dynamic Field Value
558    );
559
560=cut
561
562sub ValueIsDifferent {
563    my ( $Self, %Param ) = @_;
564
565    # check needed stuff
566    for my $Needed (qw(DynamicFieldConfig)) {
567        if ( !$Param{$Needed} ) {
568            $Kernel::OM->Get('Kernel::System::Log')->Log(
569                Priority => 'error',
570                Message  => "Need $Needed!"
571            );
572            return;
573        }
574    }
575
576    # check DynamicFieldConfig (general)
577    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
578        $Kernel::OM->Get('Kernel::System::Log')->Log(
579            Priority => 'error',
580            Message  => "The field configuration is invalid",
581        );
582        return;
583    }
584
585    # check DynamicFieldConfig (internally)
586    for my $Needed (qw(ID FieldType ObjectType)) {
587        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
588            $Kernel::OM->Get('Kernel::System::Log')->Log(
589                Priority => 'error',
590                Message  => "Need $Needed in DynamicFieldConfig!"
591            );
592            return;
593        }
594    }
595
596    # set the dynamic field specific backend
597    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
598
599    if ( !$Self->{$DynamicFieldBackend} ) {
600        $Kernel::OM->Get('Kernel::System::Log')->Log(
601            Priority => 'error',
602            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
603        );
604        return;
605    }
606
607    # use Kernel::System::VariableCheck::DataIsDifferent() as a fall back if function is not
608    #    defined in the backend
609    if ( !$Self->{$DynamicFieldBackend}->can('ValueIsDifferent') ) {
610        return DataIsDifferent(
611            Data1 => \$Param{Value1},
612            Data2 => \$Param{Value2}
613        );
614    }
615
616    # call ValueIsDifferent on the specific backend
617    return $Self->{$DynamicFieldBackend}->ValueIsDifferent(%Param);
618}
619
620=head2 ValueDelete()
621
622deletes a dynamic field value.
623
624    my $Success = $BackendObject->ValueDelete(
625        DynamicFieldConfig => $DynamicFieldConfig,      # complete config of the DynamicField
626        ObjectID           => $ObjectID,                # ID of the current object that the field
627                                                        # must be linked to, e. g. TicketID
628        UserID             => 123,
629    );
630
631=cut
632
633sub ValueDelete {
634    my ( $Self, %Param ) = @_;
635
636    # check needed stuff
637    for my $Needed (qw(DynamicFieldConfig ObjectID UserID)) {
638        if ( !$Param{$Needed} ) {
639            $Kernel::OM->Get('Kernel::System::Log')->Log(
640                Priority => 'error',
641                Message  => "Need $Needed!"
642            );
643            return;
644        }
645    }
646
647    # check DynamicFieldConfig (general)
648    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
649        $Kernel::OM->Get('Kernel::System::Log')->Log(
650            Priority => 'error',
651            Message  => "The field configuration is invalid",
652        );
653        return;
654    }
655
656    # check DynamicFieldConfig (internally)
657    for my $Needed (qw(ID FieldType ObjectType)) {
658        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
659            $Kernel::OM->Get('Kernel::System::Log')->Log(
660                Priority => 'error',
661                Message  => "Need $Needed in DynamicFieldConfig!"
662            );
663            return;
664        }
665    }
666
667    my $OldValue = $Self->ValueGet(
668        DynamicFieldConfig => $Param{DynamicFieldConfig},
669        ObjectID           => $Param{ObjectID},
670    );
671
672    # set the dynamic field specific backend
673    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
674
675    if ( !$Self->{$DynamicFieldBackend} ) {
676        $Kernel::OM->Get('Kernel::System::Log')->Log(
677            Priority => 'error',
678            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
679        );
680        return;
681    }
682
683    my $Success = $Self->{$DynamicFieldBackend}->ValueDelete(%Param);
684
685    if ( !$Success ) {
686        $Kernel::OM->Get('Kernel::System::Log')->Log(
687            Priority => 'error',
688            Message  => "Could not update field $Param{DynamicFieldConfig}->{Name} for "
689                . "$Param{DynamicFieldConfig}->{ObjectType} ID $Param{ObjectID} !",
690        );
691        return;
692    }
693
694    # set the dyanamic field object handler
695    my $DynamicFieldObjectHandler =
696        'DynamicField' . $Param{DynamicFieldConfig}->{ObjectType} . 'HandlerObject';
697
698    # If an ObjectType handler is registered, use it.
699    if ( ref $Self->{$DynamicFieldObjectHandler} ) {
700        return $Self->{$DynamicFieldObjectHandler}->PostValueSet(
701            OldValue => $OldValue,
702            %Param,
703        );
704    }
705
706    return 1;
707}
708
709=head2 AllValuesDelete()
710
711deletes all values of a dynamic field.
712
713    my $Success = $BackendObject->AllValuesDelete(
714        DynamicFieldConfig => $DynamicFieldConfig,      # complete config of the DynamicField
715        UserID             => 123,
716    );
717
718=cut
719
720sub AllValuesDelete {
721    my ( $Self, %Param ) = @_;
722
723    # check needed stuff
724    for my $Needed (qw(DynamicFieldConfig UserID)) {
725        if ( !$Param{$Needed} ) {
726            $Kernel::OM->Get('Kernel::System::Log')->Log(
727                Priority => 'error',
728                Message  => "Need $Needed!"
729            );
730            return;
731        }
732    }
733
734    # check DynamicFieldConfig (general)
735    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
736        $Kernel::OM->Get('Kernel::System::Log')->Log(
737            Priority => 'error',
738            Message  => "The field configuration is invalid",
739        );
740        return;
741    }
742
743    # check DynamicFieldConfig (internally)
744    for my $Needed (qw(ID FieldType ObjectType)) {
745        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
746            $Kernel::OM->Get('Kernel::System::Log')->Log(
747                Priority => 'error',
748                Message  => "Need $Needed in DynamicFieldConfig!"
749            );
750            return;
751        }
752    }
753
754    # set the dynamic field specific backend
755    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
756
757    if ( !$Self->{$DynamicFieldBackend} ) {
758        $Kernel::OM->Get('Kernel::System::Log')->Log(
759            Priority => 'error',
760            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
761        );
762        return;
763    }
764
765    return $Self->{$DynamicFieldBackend}->AllValuesDelete(%Param);
766}
767
768=head2 ValueValidate()
769
770validates a dynamic field value.
771
772    my $Success = $BackendObject->ValueValidate(
773        DynamicFieldConfig => $DynamicFieldConfig,      # complete config of the DynamicField
774        Value              => $Value,                   # Value to store, depends on backend type
775        UserID             => 123,
776    );
777
778=cut
779
780sub ValueValidate {
781    my ( $Self, %Param ) = @_;
782
783    # check needed stuff
784    for my $Needed (qw(DynamicFieldConfig UserID)) {
785        if ( !$Param{$Needed} ) {
786            $Kernel::OM->Get('Kernel::System::Log')->Log(
787                Priority => 'error',
788                Message  => "Need $Needed!"
789            );
790            return;
791        }
792    }
793
794    # check DynamicFieldConfig (general)
795    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
796        $Kernel::OM->Get('Kernel::System::Log')->Log(
797            Priority => 'error',
798            Message  => "The field configuration is invalid",
799        );
800        return;
801    }
802
803    # check DynamicFieldConfig (internally)
804    for my $Needed (qw(ID FieldType ObjectType)) {
805        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
806            $Kernel::OM->Get('Kernel::System::Log')->Log(
807                Priority => 'error',
808                Message  => "Need $Needed in DynamicFieldConfig!",
809            );
810            return;
811        }
812    }
813
814    # set the dynamic field specific backend
815    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
816
817    if ( !$Self->{$DynamicFieldBackend} ) {
818        $Kernel::OM->Get('Kernel::System::Log')->Log(
819            Priority => 'error',
820            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
821        );
822        return;
823    }
824
825    # call ValueValidate on the specific backend
826    return $Self->{$DynamicFieldBackend}->ValueValidate(%Param);
827}
828
829=head2 FieldValueValidate()
830
831Validates a dynamic field possible value.
832
833    my $Success = $BackendObject->FieldValueValidate(
834        DynamicFieldConfig => $DynamicFieldConfig,      # Complete config of the DynamicField.
835        Value              => $Value,                   # Value to validate from possible options.
836        UserID             => 1,
837    );
838
839=cut
840
841sub FieldValueValidate {
842    my ( $Self, %Param ) = @_;
843
844    for my $Needed (qw(DynamicFieldConfig UserID)) {
845        if ( !$Param{$Needed} ) {
846            $Kernel::OM->Get('Kernel::System::Log')->Log(
847                Priority => 'error',
848                Message  => "Need $Needed!"
849            );
850            return;
851        }
852    }
853
854    # Check DynamicFieldConfig (general).
855    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
856        $Kernel::OM->Get('Kernel::System::Log')->Log(
857            Priority => 'error',
858            Message  => "The field configuration is invalid",
859        );
860        return;
861    }
862
863    # Check DynamicFieldConfig (internally).
864    for my $Needed (qw(ID FieldType ObjectType)) {
865        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
866            $Kernel::OM->Get('Kernel::System::Log')->Log(
867                Priority => 'error',
868                Message  => "Need $Needed in DynamicFieldConfig!",
869            );
870            return;
871        }
872    }
873
874    # Set the DynamicField specific backend.
875    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
876
877    if ( !$Self->{$DynamicFieldBackend} ) {
878        $Kernel::OM->Get('Kernel::System::Log')->Log(
879            Priority => 'error',
880            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
881        );
882        return;
883    }
884
885    # Call FieldValueValidate on the specific backend if it is available.
886    if ( $Self->{$DynamicFieldBackend}->can('FieldValueValidate') ) {
887        return $Self->{$DynamicFieldBackend}->FieldValueValidate(%Param);
888    }
889
890    return $Self->{$DynamicFieldBackend}->ValueValidate(%Param);
891}
892
893=head2 ValueGet()
894
895get a dynamic field value.
896
897    my $Value = $BackendObject->ValueGet(
898        DynamicFieldConfig => $DynamicFieldConfig,      # complete config of the DynamicField
899        ObjectID           => $ObjectID,                # ID of the current object that the field
900                                                        # must be linked to, e. g. TicketID
901        ObjectName         => $ObjectName,              # Name of the current object that the field
902                                                        # must be linked to, e. g. CustomerUserLogin
903                                                        # You have to give either ObjectID OR ObjectName
904    );
905
906    Return $Value                                       # depends on backend type, i. e.
907                                                        # Text, $Value =  'a string'
908                                                        # DateTime, $Value = '1977-12-12 12:00:00'
909                                                        # Checkbox, $Value = 1
910
911=cut
912
913sub ValueGet {
914    my ( $Self, %Param ) = @_;
915
916    # check needed stuff
917    for my $Needed (qw(DynamicFieldConfig)) {
918        if ( !$Param{$Needed} ) {
919            $Kernel::OM->Get('Kernel::System::Log')->Log(
920                Priority => 'error',
921                Message  => "Need $Needed!"
922            );
923            return;
924        }
925    }
926
927    # Either ObjectID or ObjectName has to be given
928    if (
929        ( !$Param{ObjectID} && !$Param{ObjectName} )
930        || ( $Param{ObjectID} && $Param{ObjectName} )
931        )
932    {
933        $Kernel::OM->Get('Kernel::System::Log')->Log(
934            Priority => 'error',
935            Message  => "Either ObjectID or ObjectName has to be given!"
936        );
937        return;
938    }
939
940    # check DynamicFieldConfig (general)
941    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
942        $Kernel::OM->Get('Kernel::System::Log')->Log(
943            Priority => 'error',
944            Message  => "The field configuration is invalid",
945        );
946        return;
947    }
948
949    # If ObjectName has been given, fetch an ID for it
950    if ( $Param{ObjectName} ) {
951        my $ObjectIDs = $Kernel::OM->Get('Kernel::System::DynamicField')->ObjectMappingGet(
952            ObjectName => $Param{ObjectName},
953            ObjectType => $Param{DynamicFieldConfig}->{ObjectType},
954        );
955        if ( !IsHashRefWithData($ObjectIDs) || !$ObjectIDs->{ $Param{ObjectName} } ) {
956            $Kernel::OM->Get('Kernel::System::Log')->Log(
957                Priority => 'debug',
958                Message =>
959                    "Unable to fetch object mapping for object name $Param{ObjectName} and type $Param{DynamicFieldConfig}->{ObjectType}!"
960            );
961            return;
962        }
963
964        $Param{ObjectID} = $ObjectIDs->{ $Param{ObjectName} };
965    }
966
967    # check DynamicFieldConfig (internally)
968    for my $Needed (qw(ID FieldType ObjectType)) {
969        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
970            $Kernel::OM->Get('Kernel::System::Log')->Log(
971                Priority => 'error',
972                Message  => "Need $Needed in DynamicFieldConfig!",
973            );
974            return;
975        }
976    }
977
978    # set the dynamic field specific backend
979    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
980
981    if ( !$Self->{$DynamicFieldBackend} ) {
982        $Kernel::OM->Get('Kernel::System::Log')->Log(
983            Priority => 'error',
984            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
985        );
986        return;
987    }
988
989    # call ValueGet on the specific backend
990    return $Self->{$DynamicFieldBackend}->ValueGet(%Param);
991}
992
993=head2 SearchSQLGet()
994
995returns the SQL WHERE part that needs to be used to search in a particular
996dynamic field. The table must already be joined.
997
998    my $SQL = $BackendObject->SearchSQLGet(
999        DynamicFieldConfig => $DynamicFieldConfig,      # complete config of the DynamicField
1000        TableAlias         => $TableAlias,              # the alias of the already joined dynamic_field_value table to use
1001        SearchTerm         => $SearchTerm,              # What to look for. Placeholders in LIKE searches must be passed as %.
1002        Operator           => $Operator,                # One of [Equals, Like, GreaterThan, GreaterThanEquals, SmallerThan, SmallerThanEquals]
1003                                                        #   The supported operators differ for the different backends.
1004    );
1005
1006=cut
1007
1008sub SearchSQLGet {
1009    my ( $Self, %Param ) = @_;
1010
1011    # check needed stuff
1012    for my $Needed (qw(DynamicFieldConfig TableAlias Operator)) {
1013        if ( !$Param{$Needed} ) {
1014            $Kernel::OM->Get('Kernel::System::Log')->Log(
1015                Priority => 'error',
1016                Message  => "Need $Needed!"
1017            );
1018            return;
1019        }
1020    }
1021
1022    # Ignore empty searches
1023    return if ( !defined $Param{SearchTerm} || $Param{SearchTerm} eq '' );
1024
1025    # check DynamicFieldConfig (general)
1026    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
1027        $Kernel::OM->Get('Kernel::System::Log')->Log(
1028            Priority => 'error',
1029            Message  => "The field configuration is invalid",
1030        );
1031        return;
1032    }
1033
1034    # check DynamicFieldConfig (internally)
1035    for my $Needed (qw(ID FieldType ObjectType)) {
1036        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
1037            $Kernel::OM->Get('Kernel::System::Log')->Log(
1038                Priority => 'error',
1039                Message  => "Need $Needed in DynamicFieldConfig!",
1040            );
1041            return;
1042        }
1043    }
1044
1045    # set the dynamic field specific backend
1046    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
1047
1048    if ( !$Self->{$DynamicFieldBackend} ) {
1049        $Kernel::OM->Get('Kernel::System::Log')->Log(
1050            Priority => 'error',
1051            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
1052        );
1053        return;
1054    }
1055
1056    return $Self->{$DynamicFieldBackend}->SearchSQLGet(%Param);
1057}
1058
1059=head2 SearchSQLOrderFieldGet()
1060
1061returns the SQL field needed for ordering based on a dynamic field.
1062
1063    my $SQL = $BackendObject->SearchSQLOrderFieldGet(
1064        DynamicFieldConfig => $DynamicFieldConfig,      # complete config of the DynamicField
1065        TableAlias         => $TableAlias,              # the alias of the already joined dynamic_field_value table to use
1066    );
1067
1068=cut
1069
1070sub SearchSQLOrderFieldGet {
1071    my ( $Self, %Param ) = @_;
1072
1073    # check needed stuff
1074    for my $Needed (qw(DynamicFieldConfig TableAlias)) {
1075        if ( !$Param{$Needed} ) {
1076            $Kernel::OM->Get('Kernel::System::Log')->Log(
1077                Priority => 'error',
1078                Message  => "Need $Needed!"
1079            );
1080            return;
1081        }
1082    }
1083
1084    # check DynamicFieldConfig (general)
1085    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
1086        $Kernel::OM->Get('Kernel::System::Log')->Log(
1087            Priority => 'error',
1088            Message  => "The field configuration is invalid",
1089        );
1090        return;
1091    }
1092
1093    # check DynamicFieldConfig (internally)
1094    for my $Needed (qw(ID FieldType ObjectType)) {
1095        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
1096            $Kernel::OM->Get('Kernel::System::Log')->Log(
1097                Priority => 'error',
1098                Message  => "Need $Needed in DynamicFieldConfig!",
1099            );
1100            return;
1101        }
1102    }
1103
1104    # set the dynamic field specific backend
1105    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
1106
1107    if ( !$Self->{$DynamicFieldBackend} ) {
1108        $Kernel::OM->Get('Kernel::System::Log')->Log(
1109            Priority => 'error',
1110            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
1111        );
1112        return;
1113    }
1114
1115    return $Self->{$DynamicFieldBackend}->SearchSQLOrderFieldGet(%Param);
1116}
1117
1118=head2 EditFieldValueGet()
1119
1120extracts the value of a dynamic field from the param object.
1121
1122    my $Value = $BackendObject->EditFieldValueGet(
1123        DynamicFieldConfig   => $DynamicFieldConfig,    # complete config of the DynamicField
1124        ParamObject          => $ParamObject,           # the current request data
1125        LayoutObject         => $LayoutObject,          # used to transform dates to user time zone
1126        TransformDates       => 1                       # 1 || 0, default 1, to transform the dynamic fields that
1127                                                        #   use dates to the user time zone (i.e. Date, DateTime
1128                                                        #   dynamic fields)
1129        Template             => $Template,
1130        ReturnValueStructure => 0,                      # 0 || 1, default 0
1131                                                        #   Returns special structure
1132                                                        #   (only for backend internal use).
1133        ReturnTemplateStructure => 0,                   # 0 || 1, default 0
1134                                                        #   Returns the structured values as got from the http request
1135    );
1136
1137    Returns $Value;                                     # depending on each field type e.g.
1138                                                        #   $Value = 'a text';
1139                                                        #   $Value = '1977-12-12 12:00:00';
1140                                                        #   $Value = 1;
1141
1142    my $Value = $BackendObject->EditFieldValueGet(
1143        DynamicFieldConfig      => $DynamicFieldConfig, # complete config of the DynamicField
1144        ParamObject             => $ParamObject,        # the current request data
1145        TransformDates          => 0                    # 1 || 0, default 1, to transform the dynamic fields that
1146                                                        #   use dates to the user time zone (i.e. Date, DateTime
1147                                                        #   dynamic fields)
1148
1149        Template                => $Template            # stored values from DB like Search profile or Generic Agent job
1150        ReturnTemplateStructure => 1,                   # 0 || 1, default 0
1151                                                        #   Returns the structured values as got from the http request
1152                                                        #   (only for backend internal use).
1153    );
1154
1155    Returns $Value;                                     # depending on each field type e.g.
1156                                                        #   $Value = 'a text';
1157                                                        #   $Value = {
1158                                                                Used   => 1,
1159                                                                Year   => '1977',
1160                                                                Month  => '12',
1161                                                                Day    => '12',
1162                                                                Hour   => '12',
1163                                                                Minute => '00'
1164                                                            },
1165                                                        #   $Value = 1;
1166
1167=cut
1168
1169sub EditFieldValueGet {
1170    my ( $Self, %Param ) = @_;
1171
1172    # check needed stuff
1173    for my $Needed (qw(DynamicFieldConfig)) {
1174        if ( !$Param{$Needed} ) {
1175            $Kernel::OM->Get('Kernel::System::Log')->Log(
1176                Priority => 'error',
1177                Message  => "Need $Needed!"
1178            );
1179            return;
1180        }
1181    }
1182
1183    # check for the data source
1184    if ( !$Param{ParamObject} && !$Param{Template} ) {
1185        $Kernel::OM->Get('Kernel::System::Log')->Log(
1186            Priority => 'error',
1187            Message  => "Need ParamObject or Template!"
1188        );
1189        return;
1190    }
1191
1192    # define transform dates parameter
1193    if ( !defined $Param{TransformDates} ) {
1194        $Param{TransformDates} = 1;
1195    }
1196
1197    # check needed objects for transform dates
1198    if ( $Param{TransformDates} && !$Param{LayoutObject} ) {
1199        $Kernel::OM->Get('Kernel::System::Log')->Log(
1200            Priority => 'error',
1201            Message  => "Need LayoutObject to transform dates!"
1202        );
1203        return;
1204    }
1205
1206    # check DynamicFieldConfig (general)
1207    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
1208        $Kernel::OM->Get('Kernel::System::Log')->Log(
1209            Priority => 'error',
1210            Message  => "The field configuration is invalid",
1211        );
1212        return;
1213    }
1214
1215    # check DynamicFieldConfig (internally)
1216    for my $Needed (qw(ID FieldType ObjectType Name)) {
1217        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
1218            $Kernel::OM->Get('Kernel::System::Log')->Log(
1219                Priority => 'error',
1220                Message  => "Need $Needed in DynamicFieldConfig!"
1221            );
1222            return;
1223        }
1224    }
1225
1226    # set the dynamic field specific backend
1227    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
1228
1229    if ( !$Self->{$DynamicFieldBackend} ) {
1230        $Kernel::OM->Get('Kernel::System::Log')->Log(
1231            Priority => 'error',
1232            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
1233        );
1234        return;
1235    }
1236
1237    # return value from the specific backend
1238    return $Self->{$DynamicFieldBackend}->EditFieldValueGet(%Param);
1239}
1240
1241=head2 EditFieldValueValidate()
1242
1243validate the current value for the dynamic field
1244
1245    my $Result = $BackendObject->EditFieldValueValidate(
1246        DynamicFieldConfig   => $DynamicFieldConfig,      # complete config of the DynamicField
1247        PossibleValuesFilter => {                         # Optional. Some backends may support this.
1248            'Key1' => 'Value1',                           #     This may be needed to realize ACL support for ticket masks,
1249            'Key2' => 'Value2',                           #     where the possible values can be limited with and ACL.
1250        },
1251        ParamObject          => $Self->{ParamObject}      # To get the values directly from the web request
1252        Mandatory            => 1,                        # 0 or 1,
1253    );
1254
1255    Returns
1256
1257    $Result = {
1258        ServerError        => 1,                          # 0 or 1,
1259        ErrorMessage       => $ErrorMessage,              # Optional or a default will be used in error case
1260    }
1261
1262=cut
1263
1264sub EditFieldValueValidate {
1265    my ( $Self, %Param ) = @_;
1266
1267    # check needed stuff
1268    if ( !$Param{DynamicFieldConfig} ) {
1269        $Kernel::OM->Get('Kernel::System::Log')->Log(
1270            Priority => 'error',
1271            Message  => "Need DynamicFieldConfig!"
1272        );
1273        return;
1274    }
1275
1276    # check DynamicFieldConfig (general)
1277    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
1278        $Kernel::OM->Get('Kernel::System::Log')->Log(
1279            Priority => 'error',
1280            Message  => "The field configuration is invalid",
1281        );
1282        return;
1283    }
1284
1285    # check DynamicFieldConfig (internally)
1286    for my $Needed (qw(ID FieldType ObjectType Config Name)) {
1287        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
1288            $Kernel::OM->Get('Kernel::System::Log')->Log(
1289                Priority => 'error',
1290                Message  => "Need $Needed in DynamicFieldConfig!"
1291            );
1292            return;
1293        }
1294    }
1295
1296    # check PossibleValuesFilter (general)
1297    if (
1298        defined $Param{PossibleValuesFilter}
1299        && ref $Param{PossibleValuesFilter} ne 'HASH'
1300        )
1301    {
1302        $Kernel::OM->Get('Kernel::System::Log')->Log(
1303            Priority => 'error',
1304            Message  => "The possible values filter is invalid",
1305        );
1306        return;
1307    }
1308
1309    # set the dynamic field specific backend
1310    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
1311
1312    if ( !$Self->{$DynamicFieldBackend} ) {
1313        $Kernel::OM->Get('Kernel::System::Log')->Log(
1314            Priority => 'error',
1315            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
1316        );
1317        return;
1318    }
1319
1320    # return validation structure from the specific backend
1321    return $Self->{$DynamicFieldBackend}->EditFieldValueValidate(%Param);
1322
1323}
1324
1325=head2 SearchFieldRender()
1326
1327creates the field HTML to be used in search masks.
1328
1329    my $FieldHTML = $BackendObject->SearchFieldRender(
1330        DynamicFieldConfig   => $DynamicFieldConfig,      # complete config of the DynamicField
1331        ParamObject          => $ParamObject,
1332        Profile              => $ProfileData,             # search template data to load
1333        PossibleValuesFilter => {                         # optional. Some backends may support this.
1334            'Key1' => 'Value1',                           #     This may be needed to realize ACL support for ticket masks,
1335            'Key2' => 'Value2',                           #     where the possible values can be limited with and ACL.
1336        },
1337        DefaultValue         => $Value,                   # optional, depending on each field type e.g
1338                                                          #   $Value = a text';
1339                                                          #   $Value
1340                                                          #       = 'DynamicField_' . $DynamicFieldConfig->{Name} . 'StartYear=1977;'
1341                                                          #       . 'DynamicField_' . $DynamicFieldConfig->{Name} . 'StartMonth=12;'
1342                                                          #       . 'DynamicField_' . $DynamicFieldConfig->{Name} . 'StartDay=12;'
1343                                                          #       . 'DynamicField_' . $DynamicFieldConfig->{Name} . 'StartHour=00;'
1344                                                          #       . 'DynamicField_' . $DynamicFieldConfig->{Name} . 'StartMinute=00;'
1345                                                          #       . 'DynamicField_' . $DynamicFieldConfig->{Name} . 'StartSecond=00;'
1346                                                          #       . 'DynamicField_' . $DynamicFieldConfig->{Name} . 'StopYear=2011;'
1347                                                          #       . 'DynamicField_' . $DynamicFieldConfig->{Name} . 'StopMonth=09;'
1348                                                          #       . 'DynamicField_' . $DynamicFieldConfig->{Name} . 'StopDay=29;'
1349                                                          #       . 'DynamicField_' . $DynamicFieldConfig->{Name} . 'StopHour=23;'
1350                                                          #       . 'DynamicField_' . $DynamicFieldConfig->{Name} . 'StopMinute=59;'
1351                                                          #       . 'DynamicField_' . $DynamicFieldConfig->{Name} . 'StopSecond=59;';
1352                                                          #
1353                                                          #   $Value =  1;
1354        ConfirmationCheckboxes => 0,                      # or 1, to dislay confirmation checkboxes
1355        UseLabelHints          => 1,                      # or 0, default 1. To display seach hints in labels
1356        Type                   => 'some type',            # search preference type
1357
1358    );
1359
1360    Returns {
1361        Field => $HTMLString,
1362        Label => $LabelString,
1363    };
1364
1365=cut
1366
1367sub SearchFieldRender {
1368    my ( $Self, %Param ) = @_;
1369
1370    # check needed stuff
1371    for my $Needed (qw(DynamicFieldConfig LayoutObject Profile)) {
1372        if ( !$Param{$Needed} ) {
1373            $Kernel::OM->Get('Kernel::System::Log')->Log(
1374                Priority => 'error',
1375                Message  => "Need $Needed!"
1376            );
1377            return;
1378        }
1379    }
1380
1381    # check DynamicFieldConfig (general)
1382    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
1383        $Kernel::OM->Get('Kernel::System::Log')->Log(
1384            Priority => 'error',
1385            Message  => "The field configuration is invalid",
1386        );
1387        return;
1388    }
1389
1390    # check DynamicFieldConfig (internally)
1391    for my $Needed (qw(ID FieldType ObjectType)) {
1392        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
1393            $Kernel::OM->Get('Kernel::System::Log')->Log(
1394                Priority => 'error',
1395                Message  => "Need $Needed in DynamicFieldConfig!"
1396            );
1397            return;
1398        }
1399    }
1400
1401    if ( !defined $Param{UseLabelHints} ) {
1402        $Param{UseLabelHints} = 1;
1403    }
1404
1405    # set the dynamic field specific backend
1406    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
1407
1408    if ( !$Self->{$DynamicFieldBackend} ) {
1409        $Kernel::OM->Get('Kernel::System::Log')->Log(
1410            Priority => 'error',
1411            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
1412        );
1413        return;
1414    }
1415
1416    # call SearchFieldRender on the specific backend
1417    my $HTMLStrings = $Self->{$DynamicFieldBackend}->SearchFieldRender(%Param);
1418
1419    return $HTMLStrings;
1420
1421}
1422
1423=head2 SearchFieldValueGet()
1424
1425extracts the value of a dynamic field from the param object or search profile.
1426
1427    my $Value = $BackendObject->SearchFieldValueGet(
1428        DynamicFieldConfig     => $DynamicFieldConfig,    # complete config of the DynamicField
1429        ParamObject            => $ParamObject,           # the current request data
1430        Profile                => $ProfileData,           # the serach profile
1431        ReturnProfileStructure => 0,                      # 0 || 1, default 0
1432                                                          #   Returns the structured values as got from the http request
1433        Type                   => 'some type',            # search preference type
1434    );
1435
1436    Returns $Value;                                       # depending on each field type e.g.
1437                                                          #   $Value = 'a text';
1438                                                          #   $Value = {
1439                                                          #      'DynamicField_' . $DynamicFieldConfig->{Name} => 1,
1440                                                          #       ValueStart {
1441                                                          #           'DynamicField_' . $DynamicFieldConfig->{Name} . 'StartYear'   => '1977',
1442                                                          #           'DynamicField_' . $DynamicFieldConfig->{Name} . 'StartMonth'  => '12',
1443                                                          #           'DynamicField_' . $DynamicFieldConfig->{Name} . 'StartDay'    => '12',
1444                                                          #           'DynamicField_' . $DynamicFieldConfig->{Name} . 'StartHour'   => '00',
1445                                                          #           'DynamicField_' . $DynamicFieldConfig->{Name} . 'StartMinute' => '00',
1446                                                          #           'DynamicField_' . $DynamicFieldConfig->{Name} . 'StartSecond' => '00',
1447                                                          #       },
1448                                                          #       ValueStop {
1449                                                          #           'DynamicField_' . $DynamicFieldConfig->{Name} . 'StopYear'    => '2011',
1450                                                          #           'DynamicField_' . $DynamicFieldConfig->{Name} . 'StopMonth'   => '09',
1451                                                          #           'DynamicField_' . $DynamicFieldConfig->{Name} . 'StopDay'     => '29',
1452                                                          #           'DynamicField_' . $DynamicFieldConfig->{Name} . 'StopHour'    => '23',
1453                                                          #           'DynamicField_' . $DynamicFieldConfig->{Name} . 'StopMinute'  => '59',
1454                                                          #           'DynamicField_' . $DynamicFieldConfig->{Name} . 'StopSecond'  => '59',
1455                                                          #       },
1456                                                          #   },
1457                                                          #   $Value = 1;
1458
1459    my $Value = $BackendObject->SearchFieldValueGet(
1460        DynamicFieldConfig   => $DynamicFieldConfig,      # complete config of the DynamicField
1461        ParamObject          => $ParamObject,             # the current request data
1462        Profile              => $ProfileData,             # the serach profile
1463        ReturnProfileStructure => 1,                      # 0 || 1, default 0
1464                                                          #   Returns the structured values as got from the http request
1465    );
1466
1467    Returns $Value;                                       # depending on each field type e.g.
1468                                                          #   $Value =  {
1469                                                          #       'DynamicField_' . $DynamicFieldConfig->{Name} => 'a text';
1470                                                          #   };
1471                                                          #   $Value = {
1472                                                          #       'DynamicField_' . $DynamicFieldConfig->{Name}                 => 1,
1473                                                          #       'DynamicField_' . $DynamicFieldConfig->{Name} . 'StartYear'   => '1977',
1474                                                          #       'DynamicField_' . $DynamicFieldConfig->{Name} . 'StartMonth'  => '12',
1475                                                          #       'DynamicField_' . $DynamicFieldConfig->{Name} . 'StartDay'    => '12',
1476                                                          #       'DynamicField_' . $DynamicFieldConfig->{Name} . 'StartHour'   => '00',
1477                                                          #       'DynamicField_' . $DynamicFieldConfig->{Name} . 'StartMinute' => '00',
1478                                                          #       'DynamicField_' . $DynamicFieldConfig->{Name} . 'StartSecond' => '00',
1479                                                          #       'DynamicField_' . $DynamicFieldConfig->{Name} . 'StopYear'    => '2011',
1480                                                          #       'DynamicField_' . $DynamicFieldConfig->{Name} . 'StopMonth'   => '09',
1481                                                          #       'DynamicField_' . $DynamicFieldConfig->{Name} . 'StopDay'     => '29',
1482                                                          #       'DynamicField_' . $DynamicFieldConfig->{Name} . 'StopHour'    => '23',
1483                                                          #       'DynamicField_' . $DynamicFieldConfig->{Name} . 'StopMinute'  => '59',
1484                                                          #       'DynamicField_' . $DynamicFieldConfig->{Name} . 'StopSecond'  => '59',
1485                                                          #   };
1486                                                          #   $Value =  {
1487                                                          #       'DynamicField_' . $DynamicFieldConfig->{Name} = 1;
1488                                                          #   };
1489
1490=cut
1491
1492sub SearchFieldValueGet {
1493    my ( $Self, %Param ) = @_;
1494
1495    # check needed stuff
1496    for my $Needed (qw(DynamicFieldConfig)) {
1497        if ( !$Param{$Needed} ) {
1498            $Kernel::OM->Get('Kernel::System::Log')->Log(
1499                Priority => 'error',
1500                Message  => "Need $Needed!"
1501            );
1502            return;
1503        }
1504    }
1505
1506    # check ParamObject and Profile
1507    if ( !$Param{ParamObject} && !$Param{Profile} ) {
1508        $Kernel::OM->Get('Kernel::System::Log')->Log(
1509            Priority => 'error',
1510            Message  => "Need ParamObject or Profile!"
1511        );
1512        return;
1513    }
1514
1515    if ( $Param{ParamObject} && $Param{Profile} ) {
1516        $Kernel::OM->Get('Kernel::System::Log')->Log(
1517            Priority => 'error',
1518            Message  => "Only ParamObject or Profile must be specified but not both!"
1519        );
1520        return;
1521    }
1522
1523    # check if profile is a hash reference
1524    if ( $Param{Profile} && ref $Param{Profile} ne 'HASH' ) {
1525        $Kernel::OM->Get('Kernel::System::Log')->Log(
1526            Priority => 'error',
1527            Message  => "The search profile is invalid",
1528        );
1529        return;
1530    }
1531
1532    # check DynamicFieldConfig (general)
1533    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
1534        $Kernel::OM->Get('Kernel::System::Log')->Log(
1535            Priority => 'error',
1536            Message  => "The field configuration is invalid",
1537        );
1538        return;
1539    }
1540
1541    # check DynamicFieldConfig (internally)
1542    for my $Needed (qw(ID FieldType ObjectType Name)) {
1543        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
1544            $Kernel::OM->Get('Kernel::System::Log')->Log(
1545                Priority => 'error',
1546                Message  => "Need $Needed in DynamicFieldConfig!"
1547            );
1548            return;
1549        }
1550    }
1551
1552    # set the dynamic field specific backend
1553    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
1554
1555    if ( !$Self->{$DynamicFieldBackend} ) {
1556        $Kernel::OM->Get('Kernel::System::Log')->Log(
1557            Priority => 'error',
1558            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
1559        );
1560        return;
1561    }
1562
1563    # return value from the specific backend
1564    return $Self->{$DynamicFieldBackend}->SearchFieldValueGet(%Param);
1565}
1566
1567=head2 SearchFieldPreferences()
1568
1569Returns the search field preferences of the backend.
1570
1571    my $SearchFieldPreferences = $BackendObject->SearchFieldPreferences(
1572        DynamicFieldConfig => $DynamicFieldConfig,       # complete config of the DynamicField
1573    );
1574
1575    Returns (example for Date and DateTime):
1576
1577    $SearchFieldPreferences = [
1578        {
1579            Type        => 'TimePoint',
1580            LabelSuffix => 'before/after',
1581        },
1582        {
1583            Type        => 'TimeSlot',
1584            LabelSuffix => 'between',
1585        },
1586    ];
1587
1588=cut
1589
1590sub SearchFieldPreferences {
1591    my ( $Self, %Param ) = @_;
1592
1593    # check needed stuff
1594    for my $Needed (qw(DynamicFieldConfig)) {
1595        if ( !$Param{$Needed} ) {
1596            $Kernel::OM->Get('Kernel::System::Log')->Log(
1597                Priority => 'error',
1598                Message  => "Need $Needed!",
1599            );
1600            return;
1601        }
1602    }
1603
1604    # check DynamicFieldConfig (general)
1605    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
1606        $Kernel::OM->Get('Kernel::System::Log')->Log(
1607            Priority => 'error',
1608            Message  => "The field configuration is invalid",
1609        );
1610        return;
1611    }
1612
1613    # check DynamicFieldConfig (internally)
1614    for my $Needed (qw(ID FieldType ObjectType)) {
1615        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
1616            $Kernel::OM->Get('Kernel::System::Log')->Log(
1617                Priority => 'error',
1618                Message  => "Need $Needed in DynamicFieldConfig!",
1619            );
1620            return;
1621        }
1622    }
1623
1624    # set the dynamic field specific backend
1625    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
1626
1627    if ( !$Self->{$DynamicFieldBackend} ) {
1628        $Kernel::OM->Get('Kernel::System::Log')->Log(
1629            Priority => 'error',
1630            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!",
1631        );
1632        return;
1633    }
1634
1635    # verify if function is available
1636    return if !$Self->{$DynamicFieldBackend}->can('SearchFieldPreferences');
1637
1638    # call SearchFieldPreferences on the specific backend
1639    return $Self->{$DynamicFieldBackend}->SearchFieldPreferences(
1640        %Param,
1641    );
1642
1643}
1644
1645=head2 SearchFieldParameterBuild()
1646
1647build the search parameters to be passed to the search engine.
1648
1649    my $DynamicFieldSearchParameter = $BackendObject->SearchFieldParameterBuild(
1650        DynamicFieldConfig   => $DynamicFieldConfig,    # complete config of the DynamicField
1651        LayoutObject         => $LayoutObject,          # optional
1652        Profile              => $ProfileData,           # the search profile
1653        Type                 => 'some type',            # search preference type
1654    );
1655
1656    Returns
1657
1658    $DynamicFieldSearchParameter = {
1659        Parameter {
1660            Equals => $Value,                           # Available operatiors:
1661
1662                                                        #   Equals            => 123,
1663                                                        #   Like              => 'value*',
1664                                                        #   GreaterThan       => '2001-01-01 01:01:01',
1665                                                        #   GreaterThanEquals => '2001-01-01 01:01:01',
1666                                                        #   SmallerThan       => '2002-02-02 02:02:02',
1667                                                        #   SmallerThanEquals => '2002-02-02 02:02:02',
1668        },
1669        Display => $DisplayValue,                       # the value to be displayed in the search terms section
1670    };
1671
1672=cut
1673
1674sub SearchFieldParameterBuild {
1675    my ( $Self, %Param ) = @_;
1676
1677    # check needed stuff
1678    for my $Needed (qw(DynamicFieldConfig Profile)) {
1679        if ( !$Param{$Needed} ) {
1680            $Kernel::OM->Get('Kernel::System::Log')->Log(
1681                Priority => 'error',
1682                Message  => "Need $Needed!"
1683            );
1684            return;
1685        }
1686    }
1687
1688    # check DynamicFieldConfig (general)
1689    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
1690        $Kernel::OM->Get('Kernel::System::Log')->Log(
1691            Priority => 'error',
1692            Message  => "The field configuration is invalid",
1693        );
1694        return;
1695    }
1696
1697    # check DynamicFieldConfig (internally)
1698    for my $Needed (qw(ID FieldType ObjectType Name)) {
1699        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
1700            $Kernel::OM->Get('Kernel::System::Log')->Log(
1701                Priority => 'error',
1702                Message  => "Need $Needed in DynamicFieldConfig!"
1703            );
1704            return;
1705        }
1706    }
1707
1708    # set the dynamic field specific backend
1709    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
1710
1711    if ( !$Self->{$DynamicFieldBackend} ) {
1712        $Kernel::OM->Get('Kernel::System::Log')->Log(
1713            Priority => 'error',
1714            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
1715        );
1716        return;
1717    }
1718
1719    # return value from the specific backend
1720    return $Self->{$DynamicFieldBackend}->SearchFieldParameterBuild(%Param);
1721}
1722
1723=head2 ReadableValueRender()
1724
1725creates value and title strings to be used for storage (e. g. TicketHistory).
1726Produces text output and does not transform time zones of dates.
1727
1728    my $ValueStrg = $BackendObject->ReadableValueRender(
1729        DynamicFieldConfig => $DynamicFieldConfig,      # complete config of the DynamicField
1730        Value              => 'Any value',              # Optional
1731        ValueMaxChars      => 20,                       # Optional
1732        TitleMaxChars      => 20,                       # Optional
1733    );
1734
1735    Returns
1736
1737    $ValueStrg = {
1738        Title => $Title,
1739        Value => $Value,
1740    }
1741
1742=cut
1743
1744sub ReadableValueRender {
1745    my ( $Self, %Param ) = @_;
1746
1747    # check needed stuff
1748    if ( !$Param{DynamicFieldConfig} ) {
1749        $Kernel::OM->Get('Kernel::System::Log')->Log(
1750            Priority => 'error',
1751            Message  => "Need DynamicFieldConfig!"
1752        );
1753        return;
1754    }
1755
1756    # check DynamicFieldConfig (general)
1757    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
1758        $Kernel::OM->Get('Kernel::System::Log')->Log(
1759            Priority => 'error',
1760            Message  => "The field configuration is invalid",
1761        );
1762        return;
1763    }
1764
1765    # check DynamicFieldConfig (internally)
1766    for my $Needed (qw(ID FieldType ObjectType Config Name)) {
1767        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
1768            $Kernel::OM->Get('Kernel::System::Log')->Log(
1769                Priority => 'error',
1770                Message  => "Need $Needed in DynamicFieldConfig!"
1771            );
1772            return;
1773        }
1774    }
1775
1776    # set the dynamic field specific backend
1777    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
1778
1779    if ( !$Self->{$DynamicFieldBackend} ) {
1780        $Kernel::OM->Get('Kernel::System::Log')->Log(
1781            Priority => 'error',
1782            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
1783        );
1784        return;
1785    }
1786
1787    # call DisplayValueRender on the specific backend
1788    my $ValueStrg = $Self->{$DynamicFieldBackend}->ReadableValueRender(%Param);
1789
1790    return $ValueStrg;
1791}
1792
1793=head2 TemplateValueTypeGet()
1794
1795gets the value type (SCALAR or ARRAY) for a field stored on a template, like a Search Profile or a
1796Generic Agent job
1797
1798    my $ValueType = $BackendObject->TemplateValueTypeGet(
1799        DynamicFieldConfig => $DynamicFieldConfig,       # complete config of the DynamicField
1800        FieldType => 'Edit',                             # or 'Search' or 'All'
1801    );
1802
1803    returns
1804
1805    $ValueType = {
1806        'DynamicField_ . '$DynamicFieldConfig->{Name} => 'SCALAR',
1807    }
1808
1809    my $ValueType = $Self->{BackendObject}->TemplateValueTypeGet(
1810        DynamicFieldConfig => $DynamicFieldConfig,
1811        FieldType => 'Search',
1812    );
1813
1814    returns
1815
1816    $ValueType = {
1817        'Search_DynamicField_' . $DynamicFieldConfig->{Name} => 'ARRAY',
1818    }
1819
1820    my $ValueType = $Self->{BackendObject}->TemplateValueTypeGet(
1821        DynamicFieldConfig => $DynamicFieldConfig,
1822        FieldType => 'All',
1823    );
1824
1825    returns
1826
1827    $ValueType = {
1828        'DynamicField_ . '$DynamicFieldConfig->{Name} => 'SCALAR',
1829        'Search_DynamicField_' . $DynamicFieldConfig->{Name} => 'ARRAY',
1830    }
1831
1832=cut
1833
1834sub TemplateValueTypeGet {
1835    my ( $Self, %Param ) = @_;
1836
1837    # check needed stuff
1838    for my $Needed (qw(DynamicFieldConfig FieldType)) {
1839        if ( !$Param{$Needed} ) {
1840            $Kernel::OM->Get('Kernel::System::Log')->Log(
1841                Priority => 'error',
1842                Message  => "Need $Needed!"
1843            );
1844            return;
1845        }
1846    }
1847
1848    # check DynamicFieldConfig (general)
1849    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
1850        $Kernel::OM->Get('Kernel::System::Log')->Log(
1851            Priority => 'error',
1852            Message  => "The field configuration is invalid",
1853        );
1854        return;
1855    }
1856
1857    # check DynamicFieldConfig (internally)
1858    for my $Needed (qw(ID FieldType ObjectType Config Name)) {
1859        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
1860            $Kernel::OM->Get('Kernel::System::Log')->Log(
1861                Priority => 'error',
1862                Message  => "Need $Needed in DynamicFieldConfig!"
1863            );
1864            return;
1865        }
1866    }
1867
1868    # set FieldType to All as a fallback
1869    if ( $Param{FieldType} ne 'Edit' && $Param{FieldType} ne 'Search' ) {
1870        $Param{FieldType} = 'All';
1871    }
1872
1873    # set the dynamic field specific backend
1874    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
1875
1876    if ( !$Self->{$DynamicFieldBackend} ) {
1877        $Kernel::OM->Get('Kernel::System::Log')->Log(
1878            Priority => 'error',
1879            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
1880        );
1881        return;
1882    }
1883
1884    # call TemplateValueTypeGet on the specific backend
1885    my $ValueType = $Self->{$DynamicFieldBackend}->TemplateValueTypeGet(%Param);
1886
1887    return $ValueType;
1888}
1889
1890=head2 RandomValueSet()
1891
1892sets a dynamic field random value.
1893
1894    my $Result = $BackendObject->RandomValueSet(
1895        DynamicFieldConfig => $DynamicFieldConfig,      # complete config of the DynamicField
1896        ObjectID           => $ObjectID,                # ID of the current object that the field
1897                                                        # must be linked to, e. g. TicketID
1898        UserID             => 123,
1899    );
1900
1901    returns:
1902
1903    $Result {
1904        Success => 1                # or undef
1905        Value   => $RandomValue     # or undef
1906    }
1907
1908=cut
1909
1910sub RandomValueSet {
1911    my ( $Self, %Param ) = @_;
1912
1913    # check needed stuff
1914    for my $Needed (qw(DynamicFieldConfig ObjectID UserID)) {
1915        if ( !$Param{$Needed} ) {
1916            $Kernel::OM->Get('Kernel::System::Log')->Log(
1917                Priority => 'error',
1918                Message  => "Need $Needed!"
1919            );
1920            return;
1921        }
1922    }
1923
1924    # check DynamicFieldConfig (general)
1925    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
1926        $Kernel::OM->Get('Kernel::System::Log')->Log(
1927            Priority => 'error',
1928            Message  => "The field configuration is invalid",
1929        );
1930        return;
1931    }
1932
1933    # check DynamicFieldConfig (internally)
1934    for my $Needed (qw(ID FieldType ObjectType)) {
1935        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
1936            $Kernel::OM->Get('Kernel::System::Log')->Log(
1937                Priority => 'error',
1938                Message  => "Need $Needed in DynamicFieldConfig!"
1939            );
1940            return;
1941        }
1942    }
1943
1944    # set the dynamic field specific backend
1945    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
1946
1947    if ( !$Self->{$DynamicFieldBackend} ) {
1948        $Kernel::OM->Get('Kernel::System::Log')->Log(
1949            Priority => 'error',
1950            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
1951        );
1952        return;
1953    }
1954
1955    # call RandomValueSet on the specific backend
1956    my $Result = $Self->{$DynamicFieldBackend}->RandomValueSet(%Param);
1957
1958    if ( !$Result->{Success} ) {
1959        $Kernel::OM->Get('Kernel::System::Log')->Log(
1960            Priority => 'error',
1961            Message  => "Could not update field $Param{DynamicFieldConfig}->{Name} for "
1962                . "$Param{DynamicFieldConfig}->{ObjectType} ID $Param{ObjectID} !",
1963        );
1964        return;
1965    }
1966
1967    # set the dyanamic field object handler
1968    my $DynamicFieldObjectHandler =
1969        'DynamicField' . $Param{DynamicFieldConfig}->{ObjectType} . 'HandlerObject';
1970
1971    # If an ObjectType handler is registered, use it.
1972    if ( ref $Self->{$DynamicFieldObjectHandler} ) {
1973        my $PostSuccess = $Self->{$DynamicFieldObjectHandler}->PostValueSet(
1974            %Param,
1975            Value => $Result->{Value},
1976        );
1977    }
1978
1979    return $Result;
1980}
1981
1982=head2 HistoricalValuesGet()
1983
1984returns the list of database values for a defined dynamic field. This function is used to calculate
1985ACLs in Search Dialog
1986
1987    my $HistorialValues = $BackendObject->HistoricalValuesGet(
1988        DynamicFieldConfig => $DynamicFieldConfig,       # complete config of the DynamicField
1989    );
1990
1991    Returns:
1992
1993    $HistoricalValues = {
1994        '1'     => '1',
1995        'Item1' => 'Item1',
1996        'Item2' => 'Item2',
1997    }
1998
1999=cut
2000
2001sub HistoricalValuesGet {
2002    my ( $Self, %Param ) = @_;
2003
2004    # check needed stuff
2005    for my $Needed (qw(DynamicFieldConfig)) {
2006        if ( !$Param{$Needed} ) {
2007            $Kernel::OM->Get('Kernel::System::Log')->Log(
2008                Priority => 'error',
2009                Message  => "Need $Needed!"
2010            );
2011            return;
2012        }
2013    }
2014
2015    # check DynamicFieldConfig (general)
2016    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
2017        $Kernel::OM->Get('Kernel::System::Log')->Log(
2018            Priority => 'error',
2019            Message  => "The field configuration is invalid",
2020        );
2021        return;
2022    }
2023
2024    # check DynamicFieldConfig (internally)
2025    for my $Needed (qw(ID FieldType ObjectType)) {
2026        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
2027            $Kernel::OM->Get('Kernel::System::Log')->Log(
2028                Priority => 'error',
2029                Message  => "Need $Needed in DynamicFieldConfig!"
2030            );
2031            return;
2032        }
2033    }
2034
2035    # set the dynamic field specific backend
2036    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
2037
2038    if ( !$Self->{$DynamicFieldBackend} ) {
2039        $Kernel::OM->Get('Kernel::System::Log')->Log(
2040            Priority => 'error',
2041            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
2042        );
2043        return;
2044    }
2045
2046    # call HistorialValuesGet on the specific backend
2047    return $Self->{$DynamicFieldBackend}->HistoricalValuesGet(%Param);
2048}
2049
2050=head2 ValueLookup()
2051
2052returns the display value for a value key for a defined Dynamic Field. This function is meaningful
2053for those Dynamic Fields that stores a value different than the value that is shown ( e.g. a
2054Dropdown field could store Key = 1 and Display Value = One ) other fields return the same value
2055as the value key
2056
2057    my $Value = $BackendObject->ValueLookup(
2058        DynamicFieldConfig => $DynamicFieldConfig,       # complete config of the DynamicField
2059        Key                => 'sotred value',             # could also be an array ref for
2060                                                         #    MultipleSelect fields
2061        LanguageObject     => $LanguageObject,            # optional, used to get value translations
2062    );
2063
2064    Returns:
2065
2066    $Value = 'value to display';
2067
2068=cut
2069
2070sub ValueLookup {
2071    my ( $Self, %Param ) = @_;
2072
2073    # check needed stuff
2074    if ( !$Param{DynamicFieldConfig} ) {
2075        $Kernel::OM->Get('Kernel::System::Log')->Log(
2076            Priority => 'error',
2077            Message  => "Need DynamicFieldConfig!"
2078        );
2079        return;
2080    }
2081
2082    # check DynamicFieldConfig (general)
2083    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
2084        $Kernel::OM->Get('Kernel::System::Log')->Log(
2085            Priority => 'error',
2086            Message  => "The field configuration is invalid",
2087        );
2088        return;
2089    }
2090
2091    # check DynamicFieldConfig (internally)
2092    for my $Needed (qw(ID FieldType ObjectType Config Name)) {
2093        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
2094            $Kernel::OM->Get('Kernel::System::Log')->Log(
2095                Priority => 'error',
2096                Message  => "Need $Needed in DynamicFieldConfig!"
2097            );
2098            return;
2099        }
2100    }
2101
2102    # set the dynamic field specific backend
2103    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
2104
2105    if ( !$Self->{$DynamicFieldBackend} ) {
2106        $Kernel::OM->Get('Kernel::System::Log')->Log(
2107            Priority => 'error',
2108            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
2109        );
2110        return;
2111    }
2112
2113    # remove LanguageObject param if is not a real LanguageObject
2114    if ( defined $Param{LanguageObject} && ref $Param{LanguageObject} ne 'Kernel::Language' ) {
2115        delete $Param{LanguageObject};
2116    }
2117
2118    # call ValueLookup on the specific backend
2119    return $Self->{$DynamicFieldBackend}->ValueLookup(%Param);
2120}
2121
2122=head2 HasBehavior()
2123
2124checks if the dynamic field as an specified behavior
2125
2126    my $Success = $BackendObject->HasBehavior(
2127        DynamicFieldConfig => $DynamicFieldConfig,       # complete config of the DynamicField
2128        Behavior           => 'Some Behavior',           # 'IsACLReducible' to be reduded by ACLs
2129                                                         #    and updatable via AJAX
2130                                                         # 'IsNotificationEventCondition' to be used
2131                                                         #     in the notification events as a
2132                                                         #     ticket condition
2133                                                         # 'IsSortable' to sort by this field in
2134                                                         #     "Small" overviews
2135                                                         # 'IsStatsCondition' to be used in
2136                                                         #     Statistics as a condition
2137                                                         # 'IsCustomerInterfaceCapable' to make
2138                                                         #     the field usable in the customer
2139                                                         #     interface
2140                                                         # 'IsHTMLContent' to indicate that there is                                                        # 'IsCustomerInterfaceCapable' to make
2141                                                         #     HTML content (avoid duble cnversion to HTML)
2142    );
2143
2144    Returns:
2145
2146    $Success = 1;                # or undefined (if the dynamic field does not have that behavior)
2147
2148=cut
2149
2150sub HasBehavior {
2151    my ( $Self, %Param ) = @_;
2152
2153    # check needed stuff
2154    for my $Needed (qw(DynamicFieldConfig Behavior)) {
2155        if ( !$Param{$Needed} ) {
2156            $Kernel::OM->Get('Kernel::System::Log')->Log(
2157                Priority => 'error',
2158                Message  => "Need $Needed!"
2159            );
2160            return;
2161        }
2162    }
2163
2164    # check DynamicFieldConfig (general)
2165    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
2166        $Kernel::OM->Get('Kernel::System::Log')->Log(
2167            Priority => 'error',
2168            Message  => "The field configuration is invalid",
2169        );
2170        return;
2171    }
2172
2173    # check DynamicFieldConfig (internally)
2174    for my $Needed (qw(ID FieldType ObjectType)) {
2175        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
2176            $Kernel::OM->Get('Kernel::System::Log')->Log(
2177                Priority => 'error',
2178                Message  => "Need $Needed in DynamicFieldConfig!"
2179            );
2180            return;
2181        }
2182    }
2183
2184    # set the dynamic field specific backend
2185    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
2186
2187    if ( !$Self->{$DynamicFieldBackend} ) {
2188        $Kernel::OM->Get('Kernel::System::Log')->Log(
2189            Priority => 'error',
2190            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
2191        );
2192        return;
2193    }
2194
2195    # verify if function is available
2196    return if !$Self->{$DynamicFieldBackend}->can('HasBehavior');
2197
2198    # call HasBehavior on the specific backend
2199    return $Self->{$DynamicFieldBackend}->HasBehavior(%Param);
2200}
2201
2202=head2 Functions For IsACLReducible Behavior
2203
2204The following functions should be only used if the dynamic field has
2205IsACLReducible behavior
2206
2207
2208=head2 PossibleValuesGet()
2209
2210returns the list of possible values for a dynamic field
2211
2212    my $PossibleValues = $BackendObject->PossibleValuesGet(
2213        DynamicFieldConfig => $DynamicFieldConfig,       # complete config of the DynamicField
2214    );
2215
2216    Returns:
2217
2218    $PossibleValues = {
2219        ''  => '-',             # 'none' value if defined in the dynamic field configuration
2220        '1' => 'Item1',
2221        '2' => 'Item2',
2222    }
2223
2224=cut
2225
2226sub PossibleValuesGet {
2227    my ( $Self, %Param ) = @_;
2228
2229    # check needed stuff
2230    for my $Needed (qw(DynamicFieldConfig)) {
2231        if ( !$Param{$Needed} ) {
2232            $Kernel::OM->Get('Kernel::System::Log')->Log(
2233                Priority => 'error',
2234                Message  => "Need $Needed!"
2235            );
2236            return;
2237        }
2238    }
2239
2240    # check DynamicFieldConfig (general)
2241    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
2242        $Kernel::OM->Get('Kernel::System::Log')->Log(
2243            Priority => 'error',
2244            Message  => "The field configuration is invalid",
2245        );
2246        return;
2247    }
2248
2249    # check DynamicFieldConfig (internally)
2250    for my $Needed (qw(ID FieldType ObjectType)) {
2251        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
2252            $Kernel::OM->Get('Kernel::System::Log')->Log(
2253                Priority => 'error',
2254                Message  => "Need $Needed in DynamicFieldConfig!"
2255            );
2256            return;
2257        }
2258    }
2259
2260    # set the dynamic field specific backend
2261    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
2262
2263    if ( !$Self->{$DynamicFieldBackend} ) {
2264        $Kernel::OM->Get('Kernel::System::Log')->Log(
2265            Priority => 'error',
2266            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
2267        );
2268        return;
2269    }
2270
2271    # verify if function is available
2272    return if !$Self->{$DynamicFieldBackend}->can('PossibleValuesGet');
2273
2274    # call PossibleValuesGet on the specific backend
2275    return $Self->{$DynamicFieldBackend}->PossibleValuesGet(%Param);
2276}
2277
2278=head2 BuildSelectionDataGet()
2279
2280returns the list of possible values for a dynamic field as needed for BuildSelection or
2281BuildSelectionJSON if TreeView parameter is set in the DynamicFieldConfig the result will be
2282an ArrayHashRef, otherwise the result will be a HashRef.
2283
2284    my $DataValues = $BackendObject->BuildSelectionDataGet(
2285        DynamicFieldConfig => $DynamicFieldConfig,       # complete config of the DynamicField
2286        PossibleValues     => $PossibleValues,           # field possible values (could be reduced
2287                                                         #    by ACLs)
2288        Value              => $Value,                    # optional scalar, ArrayRef or HashRef
2289                                                         #    depending on dynamic field the
2290    );
2291
2292    Returns:
2293
2294    $DataValues = {
2295        ''  => '-',
2296        '1' => 'Item1',
2297        '2' => 'Item2',
2298    }
2299
2300    or
2301
2302    $DataValues = [
2303        {
2304            Key   => '',
2305            Value => '-',
2306        },
2307        {
2308            Key   => '1',
2309            Value => 'Item1'
2310        },
2311        {
2312            Key      => '1::A',
2313            Value    => 'Item1-A',
2314            Disabled => 1,
2315        },
2316        {
2317            Key      => '1::A::1',
2318            Value    => 'Item1-A-1',
2319            Selected => 1,
2320        },
2321        {
2322            Key      => '2',
2323            Value    => 'Item2',
2324        },
2325    ];
2326
2327
2328=cut
2329
2330sub BuildSelectionDataGet {
2331    my ( $Self, %Param ) = @_;
2332
2333    # check needed stuff
2334    for my $Needed (qw(DynamicFieldConfig PossibleValues)) {
2335        if ( !$Param{$Needed} ) {
2336            $Kernel::OM->Get('Kernel::System::Log')->Log(
2337                Priority => 'error',
2338                Message  => "Need $Needed!"
2339            );
2340            return;
2341        }
2342    }
2343
2344    # check DynamicFieldConfig (general)
2345    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
2346        $Kernel::OM->Get('Kernel::System::Log')->Log(
2347            Priority => 'error',
2348            Message  => "The field configuration is invalid",
2349        );
2350        return;
2351    }
2352
2353    # check DynamicFieldConfig (internally)
2354    for my $Needed (qw(ID FieldType ObjectType)) {
2355        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
2356            $Kernel::OM->Get('Kernel::System::Log')->Log(
2357                Priority => 'error',
2358                Message  => "Need $Needed in DynamicFieldConfig!"
2359            );
2360            return;
2361        }
2362    }
2363
2364    # set the dynamic field specific backend
2365    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
2366
2367    if ( !$Self->{$DynamicFieldBackend} ) {
2368        $Kernel::OM->Get('Kernel::System::Log')->Log(
2369            Priority => 'error',
2370            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
2371        );
2372        return;
2373    }
2374
2375    # verify if function is available
2376    return if !$Self->{$DynamicFieldBackend}->can('BuildSelectionDataGet');
2377
2378    # call PossibleValuesGet on the specific backend
2379    return $Self->{$DynamicFieldBackend}->BuildSelectionDataGet(%Param);
2380}
2381
2382=head2 Functions For IsStatsCondition Behavior
2383
2384The following functions should be only used if the dynamic field has IsStatsCondition behavior
2385
2386
2387=head2 StatsFieldParameterBuild()
2388
2389    my $DynamicFieldStatsParameter =  $BackendObject->StatsFieldParameterBuild(
2390        DynamicFieldConfig   => $DynamicFieldConfig,      # complete config of the DynamicField
2391        PossibleValuesFilter => ['value1', 'value2'],     # Optional. Some backends may support this.
2392                                                          #     This may be needed to realize ACL support for ticket masks,
2393                                                          #     where the possible values can be limited with and ACL.
2394    );
2395
2396    returns
2397
2398    $DynamicFieldStatsParameter = {
2399        Values => {
2400            $Key1 => $Value1,
2401            $Key2 => $Value2,
2402        },
2403        Name               => 'DynamicField_' . $DynamicFieldConfig->{Label},
2404        Element            => 'DynamicField_' . $DynamicFieldConfig->{Name},
2405        TranslatableValues => 1,
2406        TimePeriodFormat   => 'DateInputFormat',
2407        Block              => 'InputField',              # or 'MultiselectField' or 'Time'
2408    };
2409
2410=cut
2411
2412sub StatsFieldParameterBuild {
2413    my ( $Self, %Param ) = @_;
2414
2415    # check needed stuff
2416    for my $Needed (qw(DynamicFieldConfig)) {
2417        if ( !$Param{$Needed} ) {
2418            $Kernel::OM->Get('Kernel::System::Log')->Log(
2419                Priority => 'error',
2420                Message  => "Need $Needed!"
2421            );
2422            return;
2423        }
2424    }
2425
2426    # check DynamicFieldConfig (general)
2427    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
2428        $Kernel::OM->Get('Kernel::System::Log')->Log(
2429            Priority => 'error',
2430            Message  => "The field configuration is invalid",
2431        );
2432        return;
2433    }
2434
2435    # check DynamicFieldConfig (internally)
2436    for my $Needed (qw(ID FieldType ObjectType Name)) {
2437        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
2438            $Kernel::OM->Get('Kernel::System::Log')->Log(
2439                Priority => 'error',
2440                Message  => "Need $Needed in DynamicFieldConfig!"
2441            );
2442            return;
2443        }
2444    }
2445
2446    # set the dynamic field specific backend
2447    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
2448
2449    if ( !$Self->{$DynamicFieldBackend} ) {
2450        $Kernel::OM->Get('Kernel::System::Log')->Log(
2451            Priority => 'error',
2452            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
2453        );
2454        return;
2455    }
2456
2457    # return value from the specific backend
2458    return $Self->{$DynamicFieldBackend}->StatsFieldParameterBuild(%Param);
2459
2460}
2461
2462=head2 StatsSearchFieldParameterBuild()
2463
2464build the search parameters to be passed to the search engine within the stats module.
2465
2466    my $DynamicFieldStatsSearchParameter = $BackendObject->StatsSearchFieldParameterBuild(
2467        DynamicFieldConfig   => $DynamicFieldConfig,    # complete config of the DynamicField
2468        Value                => $Value,                 # the serach profile
2469    );
2470
2471    Returns
2472
2473    $DynamicFieldStatsSearchParameter = {
2474            Equals => $Value,                           # Available operatiors:
2475
2476                                                        #   Equals            => 123,
2477                                                        #   Like              => 'value*',
2478                                                        #   GreaterThan       => '2001-01-01 01:01:01',
2479                                                        #   GreaterThanEquals => '2001-01-01 01:01:01',
2480                                                        #   SmallerThan       => '2002-02-02 02:02:02',
2481                                                        #   SmallerThanEquals => '2002-02-02 02:02:02',
2482        },
2483    };
2484
2485=cut
2486
2487sub StatsSearchFieldParameterBuild {
2488    my ( $Self, %Param ) = @_;
2489
2490    # check needed stuff
2491    for my $Needed (qw(DynamicFieldConfig Value)) {
2492        if ( !$Param{$Needed} ) {
2493            $Kernel::OM->Get('Kernel::System::Log')->Log(
2494                Priority => 'error',
2495                Message  => "Need $Needed!"
2496            );
2497            return;
2498        }
2499    }
2500
2501    # check DynamicFieldConfig (general)
2502    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
2503        $Kernel::OM->Get('Kernel::System::Log')->Log(
2504            Priority => 'error',
2505            Message  => "The field configuration is invalid",
2506        );
2507        return;
2508    }
2509
2510    # check DynamicFieldConfig (internally)
2511    for my $Needed (qw(ID FieldType ObjectType Name)) {
2512        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
2513            $Kernel::OM->Get('Kernel::System::Log')->Log(
2514                Priority => 'error',
2515                Message  => "Need $Needed in DynamicFieldConfig!"
2516            );
2517            return;
2518        }
2519    }
2520
2521    # set the dynamic field specific backend
2522    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
2523
2524    if ( !$Self->{$DynamicFieldBackend} ) {
2525        $Kernel::OM->Get('Kernel::System::Log')->Log(
2526            Priority => 'error',
2527            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
2528        );
2529        return;
2530    }
2531
2532    # return value from the specific backend
2533    return $Self->{$DynamicFieldBackend}->StatsSearchFieldParameterBuild(%Param);
2534
2535}
2536
2537=head2 Functions For IsNotificationEventCondition Behavior
2538
2539The following functions should be only used if the dynamic field has IsNotificationEventCondition
2540behavior
2541
2542=head2 ObjectMatch()
2543
2544return if the current field values matches with the value got in an objects attribute structure (
2545like the result of a TicketGet() )
2546
2547    my $Match = $BackendObject->ObjectMatch(
2548        DynamicFieldConfig => $DynamicFieldConfig,       # complete config of the DynamicField
2549        Value              => $Value,                    # single value to match
2550        ObjectAttributes   => $ObjectAttributes,         # the complete set of attributes from an object
2551                                                         #      ( i.e. the result of a TicketGet() )
2552    );
2553
2554    Returns:
2555
2556    $Match                                 # 1 or 0
2557
2558=cut
2559
2560sub ObjectMatch {
2561    my ( $Self, %Param ) = @_;
2562
2563    # check needed stuff
2564    for my $Needed (qw(DynamicFieldConfig ObjectAttributes)) {
2565        if ( !$Param{$Needed} ) {
2566            $Kernel::OM->Get('Kernel::System::Log')->Log(
2567                Priority => 'error',
2568                Message  => "Need $Needed!"
2569            );
2570            return;
2571        }
2572    }
2573
2574    # check DynamicFieldConfig (general)
2575    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
2576        $Kernel::OM->Get('Kernel::System::Log')->Log(
2577            Priority => 'error',
2578            Message  => "The field configuration is invalid",
2579        );
2580        return;
2581    }
2582
2583    # check DynamicFieldConfig (internally)
2584    for my $Needed (qw(ID FieldType ObjectType)) {
2585        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
2586            $Kernel::OM->Get('Kernel::System::Log')->Log(
2587                Priority => 'error',
2588                Message  => "Need $Needed in DynamicFieldConfig!"
2589            );
2590            return;
2591        }
2592    }
2593
2594    if ( !defined $Param{Value} ) {
2595        $Kernel::OM->Get('Kernel::System::Log')->Log(
2596            Priority => 'error',
2597            Message  => "Need Value!"
2598        );
2599        return;
2600    }
2601
2602    # do not perform the action if the ObjectAttributes parameter is empty
2603    return if !IsHashRefWithData( $Param{ObjectAttributes} );
2604
2605    # set the dynamic field specific backend
2606    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
2607
2608    if ( !$Self->{$DynamicFieldBackend} ) {
2609        $Kernel::OM->Get('Kernel::System::Log')->Log(
2610            Priority => 'error',
2611            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
2612        );
2613        return;
2614    }
2615
2616    # call ObjectMatch on the specific backend
2617    return $Self->{$DynamicFieldBackend}->ObjectMatch(%Param);
2618}
2619
2620=head2 Functions For IsFiltrable Behavior
2621
2622The following functions should be only used if the dynamic field has IsFiltrable behavior
2623
2624
2625=head2 ColumnFilterValuesGet()
2626
2627get the list distinct values for a dynamic field from a list of tickets
2628
2629    my $ColumnFilterValues = $BackendObject->ColumnFilterValuesGet(
2630        DynamicFieldConfig => $DynamicFieldConfig,      #DynamicField configuraction
2631        LayoutObject       => $LayoutObject,
2632        TicketIDs          => [23, 1, 56, 74],          # array ref list of ticket IDs
2633    );
2634
2635    Returns:
2636
2637    $HistoricalValues{
2638        ValueA => 'ValueA',
2639        ValueB => 'ValueB',
2640        ValueC => 'ValueC'
2641    };
2642
2643=cut
2644
2645sub ColumnFilterValuesGet {
2646    my ( $Self, %Param ) = @_;
2647
2648    # check needed stuff
2649    for my $Needed (qw(DynamicFieldConfig LayoutObject TicketIDs)) {
2650        if ( !$Param{$Needed} ) {
2651            $Kernel::OM->Get('Kernel::System::Log')->Log(
2652                Priority => 'error',
2653                Message  => "Need $Needed!"
2654            );
2655            return;
2656        }
2657    }
2658
2659    # check DynamicFieldConfig (general)
2660    if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
2661        $Kernel::OM->Get('Kernel::System::Log')->Log(
2662            Priority => 'error',
2663            Message  => "The field configuration is invalid",
2664        );
2665        return;
2666    }
2667
2668    # check DynamicFieldConfig (internally)
2669    for my $Needed (qw(ID FieldType ObjectType)) {
2670        if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
2671            $Kernel::OM->Get('Kernel::System::Log')->Log(
2672                Priority => 'error',
2673                Message  => "Need $Needed in DynamicFieldConfig!"
2674            );
2675            return;
2676        }
2677    }
2678
2679    # set the dynamic filed specific backend
2680    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
2681
2682    if ( !$Self->{$DynamicFieldBackend} ) {
2683        $Kernel::OM->Get('Kernel::System::Log')->Log(
2684            Priority => 'error',
2685            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
2686        );
2687        return;
2688    }
2689
2690    # verify if function is available
2691    return if !$Self->{$DynamicFieldBackend}->can('ColumnFilterValuesGet');
2692
2693    # call ColumnFilterValuesGet on the specific backend
2694    return $Self->{$DynamicFieldBackend}->ColumnFilterValuesGet(
2695        %Param
2696    );
2697}
2698
2699=head2 ValueSearch()
2700
2701Searches/fetches dynamic field value.
2702
2703    my $Value = $BackendObject->ValueSearch(
2704        DynamicFieldConfig => $DynamicFieldConfig,      # complete config of the DynamicField
2705        Search             => 'search term',
2706    );
2707
2708    Returns [
2709        {
2710            ID            => 437,
2711            FieldID       => 23,
2712            ObjectID      => 133,
2713            ValueText     => 'some text',
2714            ValueDateTime => '1977-12-12 12:00:00',
2715            ValueInt      => 123,
2716        },
2717    ];
2718
2719=cut
2720
2721sub ValueSearch {
2722    my ( $Self, %Param ) = @_;
2723
2724    # check needed stuff
2725    for my $Needed (qw(DynamicFieldConfig)) {
2726        if ( !$Param{$Needed} ) {
2727            $Kernel::OM->Get('Kernel::System::Log')->Log(
2728                Priority => 'error',
2729                Message  => "Need $Needed!"
2730            );
2731            return;
2732        }
2733    }
2734
2735    # set the dynamic field specific backend
2736    my $DynamicFieldBackend = 'DynamicField' . $Param{DynamicFieldConfig}->{FieldType} . 'Object';
2737
2738    if ( !$Self->{$DynamicFieldBackend} ) {
2739        $Kernel::OM->Get('Kernel::System::Log')->Log(
2740            Priority => 'error',
2741            Message  => "Backend $Param{DynamicFieldConfig}->{FieldType} is invalid!"
2742        );
2743        return;
2744    }
2745
2746    # call ValueSearch on the specific backend
2747    return $Self->{$DynamicFieldBackend}->ValueSearch(
2748        DynamicFieldConfig => $Param{DynamicFieldConfig},
2749        Search             => $Param{Search},
2750    );
2751}
2752
27531;
2754
2755=head1 TERMS AND CONDITIONS
2756
2757This software is part of the OTRS project (L<https://otrs.org/>).
2758
2759This software comes with ABSOLUTELY NO WARRANTY. For details, see
2760the enclosed file COPYING for license information (GPL). If you
2761did not receive this file, see L<https://www.gnu.org/licenses/gpl-3.0.txt>.
2762
2763=cut
2764