# -- # Copyright (C) 2001-2019 OTRS AG, https://otrs.com/ # -- # This software comes with ABSOLUTELY NO WARRANTY. For details, see # the enclosed file COPYING for license information (GPL). If you # did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt. # -- package Kernel::System::DynamicField::Driver::BaseText; use strict; use warnings; use Kernel::System::VariableCheck qw(:all); use Kernel::Language qw(Translatable); use parent qw(Kernel::System::DynamicField::Driver::Base); our @ObjectDependencies = ( 'Kernel::System::DB', 'Kernel::System::DynamicFieldValue', 'Kernel::System::Log', ); =head1 NAME Kernel::System::DynamicField::Driver::BaseText - sub module of Kernel::System::DynamicField::Driver::Text and Kernel::System::DynamicField::Driver::TextArea =head1 DESCRIPTION Text common functions. =head1 PUBLIC INTERFACE =cut sub ValueGet { my ( $Self, %Param ) = @_; my $DFValue = $Kernel::OM->Get('Kernel::System::DynamicFieldValue')->ValueGet( FieldID => $Param{DynamicFieldConfig}->{ID}, ObjectID => $Param{ObjectID}, ); return if !$DFValue; return if !IsArrayRefWithData($DFValue); return if !IsHashRefWithData( $DFValue->[0] ); return $DFValue->[0]->{ValueText}; } sub ValueSet { my ( $Self, %Param ) = @_; my $Success = $Kernel::OM->Get('Kernel::System::DynamicFieldValue')->ValueSet( FieldID => $Param{DynamicFieldConfig}->{ID}, ObjectID => $Param{ObjectID}, Value => [ { ValueText => $Param{Value}, }, ], UserID => $Param{UserID}, ); return $Success; } sub ValueValidate { my ( $Self, %Param ) = @_; my $Success = $Kernel::OM->Get('Kernel::System::DynamicFieldValue')->ValueValidate( Value => { ValueText => $Param{Value}, }, UserID => $Param{UserID} ); my $CheckRegex = 1; if ( defined $Param{NoValidateRegex} && $Param{NoValidateRegex} ) { $CheckRegex = 0; } if ( IsArrayRefWithData( $Param{DynamicFieldConfig}->{Config}->{RegExList} ) && IsStringWithData( $Param{Value} ) && $CheckRegex ) { # check regular expressions my @RegExList = @{ $Param{DynamicFieldConfig}->{Config}->{RegExList} }; REGEXENTRY: for my $RegEx (@RegExList) { if ( $Param{Value} !~ $RegEx->{Value} ) { $Kernel::OM->Get('Kernel::System::Log')->Log( Priority => 'error', Message => "The value '$Param{Value}' is not matching /" . $RegEx->{Value} . "/ (" . $RegEx->{ErrorMessage} . ")!", ); $Success = undef; last REGEXENTRY; } } } return $Success; } sub SearchSQLGet { my ( $Self, %Param ) = @_; if ( $Param{Operator} eq 'Like' ) { my $SQL = $Kernel::OM->Get('Kernel::System::DB')->QueryCondition( Key => "$Param{TableAlias}.value_text", Value => $Param{SearchTerm}, ); return $SQL; } my %Operators = ( Equals => '=', GreaterThan => '>', GreaterThanEquals => '>=', SmallerThan => '<', SmallerThanEquals => '<=', ); if ( $Param{Operator} eq 'Empty' ) { if ( $Param{SearchTerm} ) { return " $Param{TableAlias}.value_text IS NULL "; } else { my $DatabaseType = $Kernel::OM->Get('Kernel::System::DB')->{'DB::Type'}; if ( $DatabaseType eq 'oracle' ) { return " $Param{TableAlias}.value_text IS NOT NULL "; } else { return " $Param{TableAlias}.value_text <> '' "; } } } elsif ( !$Operators{ $Param{Operator} } ) { $Kernel::OM->Get('Kernel::System::Log')->Log( 'Priority' => 'error', 'Message' => "Unsupported Operator $Param{Operator}", ); return; } my $DBObject = $Kernel::OM->Get('Kernel::System::DB'); my $Lower = ''; if ( $DBObject->GetDatabaseFunction('CaseSensitive') ) { $Lower = 'LOWER'; } my $SQL = " $Lower($Param{TableAlias}.value_text) $Operators{ $Param{Operator} } "; $SQL .= "$Lower('" . $DBObject->Quote( $Param{SearchTerm} ) . "') "; return $SQL; } sub SearchSQLOrderFieldGet { my ( $Self, %Param ) = @_; return "$Param{TableAlias}.value_text"; } sub EditFieldRender { my ( $Self, %Param ) = @_; # take config from field config my $FieldConfig = $Param{DynamicFieldConfig}->{Config}; my $FieldName = 'DynamicField_' . $Param{DynamicFieldConfig}->{Name}; my $FieldLabel = $Param{DynamicFieldConfig}->{Label}; my $Value = ''; # set the field value or default if ( $Param{UseDefaultValue} ) { $Value = ( defined $FieldConfig->{DefaultValue} ? $FieldConfig->{DefaultValue} : '' ); } $Value = $Param{Value} // $Value; # extract the dynamic field value from the web request my $FieldValue = $Self->EditFieldValueGet( %Param, ); # set values from ParamObject if present if ( defined $FieldValue ) { $Value = $FieldValue; } # check and set class if necessary my $FieldClass = 'DynamicFieldText W50pc'; if ( defined $Param{Class} && $Param{Class} ne '' ) { $FieldClass .= ' ' . $Param{Class}; } # set field as mandatory if ( $Param{Mandatory} ) { $FieldClass .= ' Validate_Required'; } # set error css class if ( $Param{ServerError} ) { $FieldClass .= ' ServerError'; } my $ValueEscaped = $Param{LayoutObject}->Ascii2Html( Text => $Value, ); my $FieldLabelEscaped = $Param{LayoutObject}->Ascii2Html( Text => $FieldLabel, ); my $HTMLString = <<"EOF"; EOF if ( $Param{Mandatory} ) { my $DivID = $FieldName . 'Error'; my $FieldRequiredMessage = $Param{LayoutObject}->{LanguageObject}->Translate("This field is required."); # for client side validation $HTMLString .= <<"EOF";

$FieldRequiredMessage

EOF } if ( $Param{ServerError} ) { my $ErrorMessage = $Param{ErrorMessage} || 'This field is required.'; $ErrorMessage = $Param{LayoutObject}->{LanguageObject}->Translate($ErrorMessage); my $DivID = $FieldName . 'ServerError'; # for server side validation $HTMLString .= <<"EOF";

$ErrorMessage

EOF } # call EditLabelRender on the common Driver my $LabelString = $Self->EditLabelRender( %Param, Mandatory => $Param{Mandatory} || '0', FieldName => $FieldName, ); my $Data = { Field => $HTMLString, Label => $LabelString, }; return $Data; } sub EditFieldValueGet { my ( $Self, %Param ) = @_; my $FieldName = 'DynamicField_' . $Param{DynamicFieldConfig}->{Name}; my $Value; # check if there is a Template and retrieve the dynamic field value from there if ( IsHashRefWithData( $Param{Template} ) && defined $Param{Template}->{$FieldName} ) { $Value = $Param{Template}->{$FieldName}; } # otherwise get dynamic field value from the web request elsif ( defined $Param{ParamObject} && ref $Param{ParamObject} eq 'Kernel::System::Web::Request' ) { $Value = $Param{ParamObject}->GetParam( Param => $FieldName ); } if ( defined $Param{ReturnTemplateStructure} && $Param{ReturnTemplateStructure} eq '1' ) { return { $FieldName => $Value, }; } # for this field the normal return an the ReturnValueStructure are the same return $Value; } sub EditFieldValueValidate { my ( $Self, %Param ) = @_; # get the field value from the http request my $Value = $Self->EditFieldValueGet( DynamicFieldConfig => $Param{DynamicFieldConfig}, ParamObject => $Param{ParamObject}, # not necessary for this Driver but place it for consistency reasons ReturnValueStructure => 1, ); my $ServerError; my $ErrorMessage; # perform necessary validations if ( $Param{Mandatory} && $Value eq '' ) { $ServerError = 1; } elsif ( IsArrayRefWithData( $Param{DynamicFieldConfig}->{Config}->{RegExList} ) && ( $Param{Mandatory} || ( !$Param{Mandatory} && $Value ne '' ) ) ) { # check regular expressions my @RegExList = @{ $Param{DynamicFieldConfig}->{Config}->{RegExList} }; REGEXENTRY: for my $RegEx (@RegExList) { if ( $Value !~ $RegEx->{Value} ) { $ServerError = 1; $ErrorMessage = $RegEx->{ErrorMessage}; last REGEXENTRY; } } } # create resulting structure my $Result = { ServerError => $ServerError, ErrorMessage => $ErrorMessage, }; return $Result; } sub DisplayValueRender { my ( $Self, %Param ) = @_; # set HTMLOutput as default if not specified if ( !defined $Param{HTMLOutput} ) { $Param{HTMLOutput} = 1; } # get raw Title and Value strings from field value my $Value = defined $Param{Value} ? $Param{Value} : ''; my $Title = $Value; # HTMLOutput transformations if ( $Param{HTMLOutput} ) { $Value = $Param{LayoutObject}->Ascii2Html( Text => $Value, Max => $Param{ValueMaxChars} || '', ); $Title = $Param{LayoutObject}->Ascii2Html( Text => $Title, Max => $Param{TitleMaxChars} || '', ); } else { if ( $Param{ValueMaxChars} && length($Value) > $Param{ValueMaxChars} ) { $Value = substr( $Value, 0, $Param{ValueMaxChars} ) . '...'; } if ( $Param{TitleMaxChars} && length($Title) > $Param{TitleMaxChars} ) { $Title = substr( $Title, 0, $Param{TitleMaxChars} ) . '...'; } } # set field link form config my $Link = $Param{DynamicFieldConfig}->{Config}->{Link} || ''; my $LinkPreview = $Param{DynamicFieldConfig}->{Config}->{LinkPreview} || ''; # create return structure my $Data = { Value => $Value, Title => $Title, Link => $Link, LinkPreview => $LinkPreview, }; return $Data; } sub SearchFieldRender { my ( $Self, %Param ) = @_; # take config from field config my $FieldConfig = $Param{DynamicFieldConfig}->{Config}; my $FieldName = 'Search_DynamicField_' . $Param{DynamicFieldConfig}->{Name}; my $FieldLabel = $Param{DynamicFieldConfig}->{Label}; # set the field value my $Value = ( defined $Param{DefaultValue} ? $Param{DefaultValue} : '' ); # get the field value, this function is always called after the profile is loaded my $FieldValue = $Self->SearchFieldValueGet(%Param); # set values from profile if present if ( defined $FieldValue ) { $Value = $FieldValue; } # check if value is an array reference (GenericAgent Jobs and NotificationEvents) if ( IsArrayRefWithData($Value) ) { $Value = @{$Value}[0]; } # check and set class if necessary my $FieldClass = 'DynamicFieldText'; my $ValueEscaped = $Param{LayoutObject}->Ascii2Html( Text => $Value, ); my $FieldLabelEscaped = $Param{LayoutObject}->Ascii2Html( Text => $FieldLabel, ); my $HTMLString = <<"EOF"; EOF my $AdditionalText; if ( $Param{UseLabelHints} ) { $AdditionalText = Translatable('e.g. Text or Te*t'); } # call EditLabelRender on the common Driver my $LabelString = $Self->EditLabelRender( %Param, FieldName => $FieldName, AdditionalText => $AdditionalText, ); my $Data = { Field => $HTMLString, Label => $LabelString, }; return $Data; } sub SearchFieldValueGet { my ( $Self, %Param ) = @_; my $Value; # get dynamic field value from param object if ( defined $Param{ParamObject} ) { $Value = $Param{ParamObject}->GetParam( Param => 'Search_DynamicField_' . $Param{DynamicFieldConfig}->{Name} ); } # otherwise get the value from the profile elsif ( defined $Param{Profile} ) { $Value = $Param{Profile}->{ 'Search_DynamicField_' . $Param{DynamicFieldConfig}->{Name} }; } else { return; } if ( defined $Param{ReturnProfileStructure} && $Param{ReturnProfileStructure} eq 1 ) { return { 'Search_DynamicField_' . $Param{DynamicFieldConfig}->{Name} => $Value, }; } return $Value; } sub SearchFieldParameterBuild { my ( $Self, %Param ) = @_; # get field value my $Value = $Self->SearchFieldValueGet(%Param); # set operator my $Operator = 'Equals'; # search for a wild card in the value if ( $Value && ( $Value =~ m{\*} || $Value =~ m{\|\|} ) ) { # change operator $Operator = 'Like'; } # return search parameter structure return { Parameter => { $Operator => $Value, }, Display => $Value, }; } sub StatsFieldParameterBuild { my ( $Self, %Param ) = @_; return { Name => $Param{DynamicFieldConfig}->{Label}, Element => 'DynamicField_' . $Param{DynamicFieldConfig}->{Name}, Block => 'InputField', }; } sub StatsSearchFieldParameterBuild { my ( $Self, %Param ) = @_; my $Value = $Param{Value}; # set operator my $Operator = 'Equals'; # search for a wild card in the value if ( $Value && $Value =~ m{\*} ) { # change operator $Operator = 'Like'; } return { $Operator => $Value, }; } sub ReadableValueRender { my ( $Self, %Param ) = @_; my $Value = defined $Param{Value} ? $Param{Value} : ''; my $Title = $Value; # cut strings if needed if ( $Param{ValueMaxChars} && length($Value) > $Param{ValueMaxChars} ) { $Value = substr( $Value, 0, $Param{ValueMaxChars} ) . '...'; } if ( $Param{TitleMaxChars} && length($Title) > $Param{TitleMaxChars} ) { $Title = substr( $Title, 0, $Param{TitleMaxChars} ) . '...'; } # create return structure my $Data = { Value => $Value, Title => $Title, }; return $Data; } sub TemplateValueTypeGet { my ( $Self, %Param ) = @_; my $FieldName = 'DynamicField_' . $Param{DynamicFieldConfig}->{Name}; # set the field types my $EditValueType = 'SCALAR'; my $SearchValueType = 'SCALAR'; # return the correct structure if ( $Param{FieldType} eq 'Edit' ) { return { $FieldName => $EditValueType, }; } elsif ( $Param{FieldType} eq 'Search' ) { return { 'Search_' . $FieldName => $SearchValueType, }; } else { return { $FieldName => $EditValueType, 'Search_' . $FieldName => $SearchValueType, }; } } sub RandomValueSet { my ( $Self, %Param ) = @_; my $Value = int( rand(500) ); my $Success = $Self->ValueSet( %Param, Value => $Value, ); if ( !$Success ) { return { Success => 0, }; } return { Success => 1, Value => $Value, }; } sub ObjectMatch { my ( $Self, %Param ) = @_; my $FieldName = 'DynamicField_' . $Param{DynamicFieldConfig}->{Name}; # return false if field is not defined return 0 if ( !defined $Param{ObjectAttributes}->{$FieldName} ); # return false if not match if ( $Param{ObjectAttributes}->{$FieldName} ne $Param{Value} ) { return 0; } return 1; } sub HistoricalValuesGet { my ( $Self, %Param ) = @_; # get historical values from database my $HistoricalValues = $Kernel::OM->Get('Kernel::System::DynamicFieldValue')->HistoricalValueGet( FieldID => $Param{DynamicFieldConfig}->{ID}, ValueType => 'Text', ); # return the historical values from database return $HistoricalValues; } sub ValueLookup { my ( $Self, %Param ) = @_; my $Value = defined $Param{Key} ? $Param{Key} : ''; return $Value; } 1; =head1 TERMS AND CONDITIONS This software is part of the OTRS project (L). This software comes with ABSOLUTELY NO WARRANTY. For details, see the enclosed file COPYING for license information (GPL). If you did not receive this file, see L. =cut