# --
# 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