# -- # 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::TextArea; use strict; use warnings; use Kernel::System::VariableCheck qw(:all); use parent qw(Kernel::System::DynamicField::Driver::BaseText); our @ObjectDependencies = ( 'Kernel::Config', 'Kernel::System::DynamicFieldValue', 'Kernel::System::Main', ); =head1 NAME Kernel::System::DynamicField::Driver::TextArea =head1 DESCRIPTION DynamicFields TextArea Driver delegate =head1 PUBLIC INTERFACE This module implements the public interface of L. Please look there for a detailed reference of the functions. =head2 new() usually, you want to create an instance of this by using Kernel::System::DynamicField::Backend->new(); =cut sub new { my ( $Type, %Param ) = @_; # allocate new hash for object my $Self = {}; bless( $Self, $Type ); # set the maximum length for the text-area fields to still be a searchable field in some # databases $Self->{MaxLength} = 3800; # set field behaviors $Self->{Behaviors} = { 'IsACLReducible' => 0, 'IsNotificationEventCondition' => 1, 'IsSortable' => 0, 'IsFiltrable' => 0, 'IsStatsCondition' => 1, 'IsCustomerInterfaceCapable' => 1, 'IsLikeOperatorCapable' => 1, }; # get the Dynamic Field Backend custom extensions my $DynamicFieldDriverExtensions = $Kernel::OM->Get('Kernel::Config')->Get('DynamicFields::Extension::Driver::TextArea'); EXTENSION: for my $ExtensionKey ( sort keys %{$DynamicFieldDriverExtensions} ) { # skip invalid extensions next EXTENSION if !IsHashRefWithData( $DynamicFieldDriverExtensions->{$ExtensionKey} ); # create a extension config shortcut my $Extension = $DynamicFieldDriverExtensions->{$ExtensionKey}; # check if extension has a new module if ( $Extension->{Module} ) { # check if module can be loaded if ( !$Kernel::OM->Get('Kernel::System::Main')->RequireBaseClass( $Extension->{Module} ) ) { die "Can't load dynamic fields backend module" . " $Extension->{Module}! $@"; } } # check if extension contains more behaviors if ( IsHashRefWithData( $Extension->{Behaviors} ) ) { %{ $Self->{Behaviors} } = ( %{ $Self->{Behaviors} }, %{ $Extension->{Behaviors} } ); } } return $Self; } 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; } # set the rows number my $RowsNumber = defined $FieldConfig->{Rows} && $FieldConfig->{Rows} ? $FieldConfig->{Rows} : '7'; # set the cols number my $ColsNumber = defined $FieldConfig->{Cols} && $FieldConfig->{Cols} ? $FieldConfig->{Cols} : '42'; # check and set class if necessary my $FieldClass = 'DynamicFieldTextArea'; 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'; } # set validation class for maximum characters $FieldClass .= ' Validate_MaxLength'; my $ValueEscaped = $Param{LayoutObject}->Ascii2Html( Text => $Value, ); my $FieldLabelEscaped = $Param{LayoutObject}->Ascii2Html( Text => $FieldLabel, ); # create field HTML # the XHTML definition does not support maxlength attribute for a text-area field, # we use data-maxlength instead # Notice that some browsers count new lines \n\r as only 1 character. In these cases the # validation framework might generate an error while the user is still capable to enter text in the # text-area. Otherwise the maxlength property will prevent to enter more text than the maximum. my $MaxLength = $Param{MaxLength} // $Self->{MaxLength}; my $HTMLString = <<"EOF"; EOF # for client side validation my $DivID = $FieldName . 'Error'; my $ErrorMessage1 = $Param{LayoutObject}->{LanguageObject}->Translate("This field is required or"); my $ErrorMessage2 = $Param{LayoutObject}->{LanguageObject}->Translate("The field content is too long!"); my $ErrorMessage3 = $Param{LayoutObject}->{LanguageObject}->Translate( "Maximum size is %s characters.", $MaxLength ); if ( $Param{Mandatory} ) { $HTMLString .= <<"EOF";

$ErrorMessage1 $ErrorMessage2 $ErrorMessage3

EOF } else { $HTMLString .= <<"EOF";

$ErrorMessage2 $ErrorMessage3

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 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 ( length $Value > $Self->{MaxLength} ) { $ServerError = 1; $ErrorMessage = "The field content is too long! Maximum size is $Self->{MaxLength} characters."; } 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, HTMLResultMode => 1, 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} ) . '...'; } } # this field type does not support the Link Feature my $Link; # create return structure my $Data = { Value => $Value, Title => $Title, Link => $Link, }; 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 # call EditLabelRender on the common Driver my $LabelString = $Self->EditLabelRender( %Param, FieldName => $FieldName, ); my $Data = { Field => $HTMLString, Label => $LabelString, }; return $Data; } 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