init III
This commit is contained in:
2763
Perl OTRS/Kernel/System/DynamicField/Backend.pm
Normal file
2763
Perl OTRS/Kernel/System/DynamicField/Backend.pm
Normal file
File diff suppressed because it is too large
Load Diff
254
Perl OTRS/Kernel/System/DynamicField/Driver/Base.pm
Normal file
254
Perl OTRS/Kernel/System/DynamicField/Driver/Base.pm
Normal file
@@ -0,0 +1,254 @@
|
||||
# --
|
||||
# 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::Base;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Kernel::System::VariableCheck qw(:all);
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::System::DynamicFieldValue',
|
||||
'Kernel::System::Log',
|
||||
);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Kernel::System::DynamicField::Driver::Base - common fields backend functions
|
||||
|
||||
=head1 PUBLIC INTERFACE
|
||||
|
||||
=cut
|
||||
|
||||
sub ValueIsDifferent {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# special cases where the values are different but they should be reported as equals
|
||||
return if !defined $Param{Value1} && ( defined $Param{Value2} && $Param{Value2} eq '' );
|
||||
return if !defined $Param{Value2} && ( defined $Param{Value1} && $Param{Value1} eq '' );
|
||||
|
||||
# compare the results
|
||||
return DataIsDifferent(
|
||||
Data1 => \$Param{Value1},
|
||||
Data2 => \$Param{Value2}
|
||||
);
|
||||
}
|
||||
|
||||
sub ValueDelete {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
my $Success = $Kernel::OM->Get('Kernel::System::DynamicFieldValue')->ValueDelete(
|
||||
FieldID => $Param{DynamicFieldConfig}->{ID},
|
||||
ObjectID => $Param{ObjectID},
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
return $Success;
|
||||
}
|
||||
|
||||
sub AllValuesDelete {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
my $Success = $Kernel::OM->Get('Kernel::System::DynamicFieldValue')->AllValuesDelete(
|
||||
FieldID => $Param{DynamicFieldConfig}->{ID},
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
return $Success;
|
||||
}
|
||||
|
||||
sub HasBehavior {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# return fail if Behaviors hash does not exists
|
||||
return if !IsHashRefWithData( $Self->{Behaviors} );
|
||||
|
||||
# return success if the dynamic field has the expected behavior
|
||||
return IsPositiveInteger( $Self->{Behaviors}->{ $Param{Behavior} } );
|
||||
}
|
||||
|
||||
sub SearchFieldPreferences {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
my @Preferences = (
|
||||
{
|
||||
Type => '',
|
||||
LabelSuffix => '',
|
||||
},
|
||||
);
|
||||
|
||||
return \@Preferences;
|
||||
}
|
||||
|
||||
=head2 EditLabelRender()
|
||||
|
||||
creates the label HTML to be used in edit masks.
|
||||
|
||||
my $LabelHTML = $BackendObject->EditLabelRender(
|
||||
DynamicFieldConfig => $DynamicFieldConfig, # complete config of the DynamicField
|
||||
FieldName => 'TheField', # the value to be set on the 'for' attribute
|
||||
AdditionalText => 'Between' # other text to be placed next to FieldName
|
||||
Mandatory => 1, # 0 or 1,
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub EditLabelRender {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
for my $Needed (qw(DynamicFieldConfig FieldName)) {
|
||||
if ( !$Param{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed!"
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# check DynamicFieldConfig (general)
|
||||
if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "The field configuration is invalid",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# check DynamicFieldConfig (internally)
|
||||
for my $Needed (qw(Label)) {
|
||||
if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed in DynamicFieldConfig!"
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
my $Name = $Param{FieldName};
|
||||
my $LabelText = $Param{DynamicFieldConfig}->{Label};
|
||||
|
||||
my $LabelID = 'Label' . $Param{FieldName};
|
||||
my $HTMLString = '';
|
||||
|
||||
if ( $Param{Mandatory} ) {
|
||||
|
||||
# opening tag
|
||||
$HTMLString = <<"EOF";
|
||||
<label id="$LabelID" for="$Name" class="Mandatory">
|
||||
<span class="Marker">*</span>
|
||||
EOF
|
||||
}
|
||||
else {
|
||||
|
||||
# opening tag
|
||||
$HTMLString = <<"EOF";
|
||||
<label id="$LabelID" for="$Name">
|
||||
EOF
|
||||
}
|
||||
|
||||
# text
|
||||
$HTMLString .= $Param{LayoutObject}->Ascii2Html(
|
||||
Text => $Param{LayoutObject}->{LanguageObject}->Translate("$LabelText")
|
||||
);
|
||||
if ( $Param{AdditionalText} ) {
|
||||
$HTMLString .= " (";
|
||||
$HTMLString .= $Param{LayoutObject}->Ascii2Html(
|
||||
Text => $Param{LayoutObject}->{LanguageObject}->Translate("$Param{AdditionalText}")
|
||||
);
|
||||
$HTMLString .= ")";
|
||||
}
|
||||
$HTMLString .= ":\n";
|
||||
|
||||
# closing tag
|
||||
$HTMLString .= <<"EOF";
|
||||
</label>
|
||||
EOF
|
||||
|
||||
return $HTMLString;
|
||||
}
|
||||
|
||||
=head2 ValueSearch()
|
||||
|
||||
Searches/fetches dynamic field value.
|
||||
|
||||
my $Value = $BackendObject->ValueSearch(
|
||||
DynamicFieldConfig => $DynamicFieldConfig, # complete config of the DynamicField
|
||||
Search => 'test',
|
||||
);
|
||||
|
||||
Returns [
|
||||
{
|
||||
ID => 437,
|
||||
FieldID => 23,
|
||||
ObjectID => 133,
|
||||
ValueText => 'some text',
|
||||
ValueDateTime => '1977-12-12 12:00:00',
|
||||
ValueInt => 123,
|
||||
},
|
||||
];
|
||||
|
||||
=cut
|
||||
|
||||
sub ValueSearch {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check mandatory parameters
|
||||
if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need DynamicFieldConfig!"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
my $SearchTerm = $Param{Search};
|
||||
my $Operator = 'Equals';
|
||||
if ( $Self->HasBehavior( Behavior => 'IsLikeOperatorCapable' ) ) {
|
||||
$SearchTerm = '%' . $Param{Search} . '%';
|
||||
$Operator = 'Like';
|
||||
}
|
||||
|
||||
my $SearchSQL = $Self->SearchSQLGet(
|
||||
DynamicFieldConfig => $Param{DynamicFieldConfig},
|
||||
TableAlias => 'dynamic_field_value',
|
||||
SearchTerm => $SearchTerm,
|
||||
Operator => $Operator,
|
||||
);
|
||||
|
||||
if ( !defined $SearchSQL || !length $SearchSQL ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Error generating search SQL!"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
my $Values = $Kernel::OM->Get('Kernel::System::DynamicFieldValue')->ValueSearch(
|
||||
FieldID => $Param{DynamicFieldConfig}->{ID},
|
||||
Search => $Param{Search},
|
||||
SearchSQL => $SearchSQL,
|
||||
);
|
||||
|
||||
return $Values;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 TERMS AND CONDITIONS
|
||||
|
||||
This software is part of the OTRS project (L<https://otrs.org/>).
|
||||
|
||||
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<https://www.gnu.org/licenses/gpl-3.0.txt>.
|
||||
|
||||
=cut
|
||||
1235
Perl OTRS/Kernel/System/DynamicField/Driver/BaseDateTime.pm
Normal file
1235
Perl OTRS/Kernel/System/DynamicField/Driver/BaseDateTime.pm
Normal file
File diff suppressed because it is too large
Load Diff
1017
Perl OTRS/Kernel/System/DynamicField/Driver/BaseSelect.pm
Normal file
1017
Perl OTRS/Kernel/System/DynamicField/Driver/BaseSelect.pm
Normal file
File diff suppressed because it is too large
Load Diff
663
Perl OTRS/Kernel/System/DynamicField/Driver/BaseText.pm
Normal file
663
Perl OTRS/Kernel/System/DynamicField/Driver/BaseText.pm
Normal file
@@ -0,0 +1,663 @@
|
||||
# --
|
||||
# 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";
|
||||
<input type="text" class="$FieldClass" id="$FieldName" name="$FieldName" title="$FieldLabelEscaped" value="$ValueEscaped" />
|
||||
EOF
|
||||
|
||||
if ( $Param{Mandatory} ) {
|
||||
my $DivID = $FieldName . 'Error';
|
||||
|
||||
my $FieldRequiredMessage = $Param{LayoutObject}->{LanguageObject}->Translate("This field is required.");
|
||||
|
||||
# for client side validation
|
||||
$HTMLString .= <<"EOF";
|
||||
<div id="$DivID" class="TooltipErrorMessage">
|
||||
<p>
|
||||
$FieldRequiredMessage
|
||||
</p>
|
||||
</div>
|
||||
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";
|
||||
<div id="$DivID" class="TooltipErrorMessage">
|
||||
<p>
|
||||
$ErrorMessage
|
||||
</p>
|
||||
</div>
|
||||
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";
|
||||
<input type="text" class="$FieldClass" id="$FieldName" name="$FieldName" title="$FieldLabelEscaped" value="$ValueEscaped" />
|
||||
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<https://otrs.org/>).
|
||||
|
||||
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<https://www.gnu.org/licenses/gpl-3.0.txt>.
|
||||
|
||||
=cut
|
||||
891
Perl OTRS/Kernel/System/DynamicField/Driver/Checkbox.pm
Normal file
891
Perl OTRS/Kernel/System/DynamicField/Driver/Checkbox.pm
Normal file
@@ -0,0 +1,891 @@
|
||||
# --
|
||||
# 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::Checkbox;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Kernel::System::VariableCheck qw(:all);
|
||||
|
||||
use parent qw(Kernel::System::DynamicField::Driver::Base);
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::Config',
|
||||
'Kernel::System::DB',
|
||||
'Kernel::System::DynamicFieldValue',
|
||||
'Kernel::System::Ticket::ColumnFilter',
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::Main',
|
||||
);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Kernel::System::DynamicField::Driver::Checkbox
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
DynamicFields Checkbox Driver delegate
|
||||
|
||||
=head1 PUBLIC INTERFACE
|
||||
|
||||
This module implements the public interface of L<Kernel::System::DynamicField::Backend>.
|
||||
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 field behaviors
|
||||
$Self->{Behaviors} = {
|
||||
'IsACLReducible' => 0,
|
||||
'IsNotificationEventCondition' => 1,
|
||||
'IsSortable' => 1,
|
||||
'IsFiltrable' => 1,
|
||||
'IsStatsCondition' => 1,
|
||||
'IsCustomerInterfaceCapable' => 1,
|
||||
};
|
||||
|
||||
# get the Dynamic Field Backend custom extensions
|
||||
my $DynamicFieldDriverExtensions
|
||||
= $Kernel::OM->Get('Kernel::Config')->Get('DynamicFields::Extension::Driver::Checkbox');
|
||||
|
||||
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 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]->{ValueInt};
|
||||
}
|
||||
|
||||
sub ValueSet {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check value for just 1 or 0
|
||||
if ( defined $Param{Value} && !$Param{Value} ) {
|
||||
$Param{Value} = 0;
|
||||
}
|
||||
elsif ( $Param{Value} && $Param{Value} !~ m{\A [0|1]? \z}xms ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Value $Param{Value} is invalid for Checkbox fields!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
my $Success = $Kernel::OM->Get('Kernel::System::DynamicFieldValue')->ValueSet(
|
||||
FieldID => $Param{DynamicFieldConfig}->{ID},
|
||||
ObjectID => $Param{ObjectID},
|
||||
Value => [
|
||||
{
|
||||
ValueInt => $Param{Value},
|
||||
},
|
||||
],
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
return $Success;
|
||||
}
|
||||
|
||||
sub ValueValidate {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check value for just 1 or 0
|
||||
if ( defined $Param{Value} && !$Param{Value} ) {
|
||||
$Param{Value} = 0;
|
||||
}
|
||||
elsif ( $Param{Value} && $Param{Value} !~ m{\A [0|1]? \z}xms ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Value $Param{Value} is invalid for Checkbox fields!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
my $Success = $Kernel::OM->Get('Kernel::System::DynamicFieldValue')->ValueValidate(
|
||||
Value => {
|
||||
ValueInt => $Param{Value},
|
||||
},
|
||||
UserID => $Param{UserID}
|
||||
);
|
||||
|
||||
return $Success;
|
||||
}
|
||||
|
||||
sub SearchSQLGet {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
if ( !IsInteger( $Param{SearchTerm} ) ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
'Priority' => 'error',
|
||||
'Message' => "Unsupported Search Term $Param{SearchTerm}, should be an integer",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
my %Operators = (
|
||||
Equals => '=',
|
||||
);
|
||||
|
||||
if ( $Param{Operator} eq 'Empty' ) {
|
||||
if ( $Param{SearchTerm} ) {
|
||||
return " $Param{TableAlias}.value_int IS NULL ";
|
||||
}
|
||||
else {
|
||||
return " $Param{TableAlias}.value_int IS NOT NULL ";
|
||||
}
|
||||
}
|
||||
elsif ( !$Operators{ $Param{Operator} } ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
'Priority' => 'error',
|
||||
'Message' => "Unsupported Operator $Param{Operator}",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
my $SQL = " $Param{TableAlias}.value_int $Operators{ $Param{Operator} } ";
|
||||
$SQL
|
||||
.= $Kernel::OM->Get('Kernel::System::DB')->Quote( $Param{SearchTerm}, 'Integer' ) . ' ';
|
||||
return $SQL;
|
||||
}
|
||||
|
||||
sub SearchSQLOrderFieldGet {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
return "$Param{TableAlias}.value_int";
|
||||
}
|
||||
|
||||
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 = $FieldConfig->{DefaultValue} || '';
|
||||
}
|
||||
$Value = $Param{Value} // $Value;
|
||||
|
||||
# extract the dynamic field value from the web request
|
||||
my $FieldValue = $Self->EditFieldValueGet(
|
||||
ReturnValueStructure => 1,
|
||||
%Param,
|
||||
);
|
||||
|
||||
# set values from ParamObject if present
|
||||
if ( defined $FieldValue && IsHashRefWithData($FieldValue) ) {
|
||||
if (
|
||||
!defined $FieldValue->{FieldValue}
|
||||
&& defined $FieldValue->{UsedValue}
|
||||
&& $FieldValue->{UsedValue} eq '1'
|
||||
)
|
||||
{
|
||||
$Value = '0';
|
||||
}
|
||||
elsif (
|
||||
defined $FieldValue->{FieldValue}
|
||||
&& $FieldValue->{FieldValue} eq '1'
|
||||
&& defined $FieldValue->{UsedValue}
|
||||
&& $FieldValue->{UsedValue} eq '1'
|
||||
)
|
||||
{
|
||||
$Value = '1';
|
||||
}
|
||||
}
|
||||
|
||||
# set as checked if necessary
|
||||
my $FieldChecked = ( defined $Value && $Value eq '1' ? 'checked="checked"' : '' );
|
||||
|
||||
# check and set class if necessary
|
||||
my $FieldClass = 'DynamicFieldCheckbox';
|
||||
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 $FieldNameUsed = $FieldName . "Used";
|
||||
|
||||
my $HTMLString = <<"EOF";
|
||||
<input type="hidden" id="$FieldNameUsed" name="$FieldNameUsed" value="1" />
|
||||
EOF
|
||||
|
||||
if ( $Param{ConfirmationNeeded} ) {
|
||||
|
||||
# set checked property
|
||||
my $FieldUsedChecked0 = '';
|
||||
my $FieldUsedChecked1 = '';
|
||||
if ( $FieldValue->{UsedValue} ) {
|
||||
$FieldUsedChecked1 = 'checked="checked"';
|
||||
}
|
||||
else {
|
||||
$FieldUsedChecked0 = 'checked="checked"';
|
||||
}
|
||||
|
||||
my $FieldNameUsed0 = $FieldNameUsed . '0';
|
||||
my $FieldNameUsed1 = $FieldNameUsed . '1';
|
||||
my $TranslatedDesc = $Param{LayoutObject}->{LanguageObject}->Translate(
|
||||
'Ignore this field.',
|
||||
);
|
||||
$HTMLString = <<"EOF";
|
||||
<input type="radio" id="$FieldNameUsed0" name="$FieldNameUsed" value="" $FieldUsedChecked0 />
|
||||
$TranslatedDesc
|
||||
<div class="clear"></div>
|
||||
<input type="radio" id="$FieldNameUsed1" name="$FieldNameUsed" value="1" $FieldUsedChecked1 />
|
||||
EOF
|
||||
}
|
||||
|
||||
my $FieldLabelEscaped = $Param{LayoutObject}->Ascii2Html(
|
||||
Text => $FieldLabel,
|
||||
);
|
||||
|
||||
$HTMLString .= <<"EOF";
|
||||
<input type="checkbox" class="$FieldClass" id="$FieldName" name="$FieldName" title="$FieldLabelEscaped" $FieldChecked value="1" />
|
||||
EOF
|
||||
|
||||
if ( $Param{Mandatory} ) {
|
||||
my $DivID = $FieldName . 'Error';
|
||||
|
||||
my $FieldRequiredMessage = $Param{LayoutObject}->{LanguageObject}->Translate("This field is required.");
|
||||
|
||||
# for client side validation
|
||||
$HTMLString .= <<"EOF";
|
||||
<div id="$DivID" class="TooltipErrorMessage">
|
||||
<p>
|
||||
$FieldRequiredMessage
|
||||
</p>
|
||||
</div>
|
||||
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";
|
||||
<div id="$DivID" class="TooltipErrorMessage">
|
||||
<p>
|
||||
$ErrorMessage
|
||||
</p>
|
||||
</div>
|
||||
EOF
|
||||
}
|
||||
|
||||
if ( $Param{AJAXUpdate} ) {
|
||||
|
||||
my $FieldsToUpdate = '';
|
||||
if ( IsArrayRefWithData( $Param{UpdatableFields} ) ) {
|
||||
|
||||
# Remove current field from updatable fields list.
|
||||
my @FieldsToUpdate = grep { $_ ne $FieldName } @{ $Param{UpdatableFields} };
|
||||
|
||||
# Quote all fields, put commas between them.
|
||||
$FieldsToUpdate = join( ', ', map {"'$_'"} @FieldsToUpdate );
|
||||
}
|
||||
|
||||
# Add JS to call FormUpdate() on change event.
|
||||
$Param{LayoutObject}->AddJSOnDocumentComplete( Code => <<"EOF");
|
||||
\$('#$FieldName').on('change', function () {
|
||||
Core.AJAX.FormUpdate(\$(this).parents('form'), 'AJAXUpdate', '$FieldName', [ $FieldsToUpdate ]);
|
||||
});
|
||||
EOF
|
||||
}
|
||||
|
||||
# call EditLabelRender on the common backend
|
||||
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 %Data;
|
||||
|
||||
# check if there is a Template and retrieve the dynamic field value from there
|
||||
if (
|
||||
IsHashRefWithData( $Param{Template} ) && (
|
||||
defined $Param{Template}->{$FieldName}
|
||||
|| defined $Param{Template}->{ $FieldName . 'Used' }
|
||||
)
|
||||
)
|
||||
{
|
||||
# get dynamic field value form Template
|
||||
$Data{FieldValue} = $Param{Template}->{$FieldName};
|
||||
|
||||
# get dynamic field used value form Template
|
||||
$Data{UsedValue} = $Param{Template}->{ $FieldName . 'Used' };
|
||||
}
|
||||
|
||||
# otherwise get dynamic field value from the web request
|
||||
elsif (
|
||||
defined $Param{ParamObject}
|
||||
&& ref $Param{ParamObject} eq 'Kernel::System::Web::Request'
|
||||
)
|
||||
{
|
||||
|
||||
# get dynamic field value from param
|
||||
$Data{FieldValue} = $Param{ParamObject}->GetParam( Param => $FieldName );
|
||||
|
||||
# get dynamic field used value from param
|
||||
$Data{UsedValue} = $Param{ParamObject}->GetParam( Param => $FieldName . 'Used' );
|
||||
}
|
||||
|
||||
# check if return value structure is needed
|
||||
if ( defined $Param{ReturnValueStructure} && $Param{ReturnValueStructure} eq '1' ) {
|
||||
return \%Data;
|
||||
}
|
||||
|
||||
# check if return template structure is needed
|
||||
if ( defined $Param{ReturnTemplateStructure} && $Param{ReturnTemplateStructure} eq '1' ) {
|
||||
return {
|
||||
$FieldName => $Data{FieldValue},
|
||||
$FieldName . 'Used' => $Data{UsedValue},
|
||||
};
|
||||
}
|
||||
|
||||
# return undef if the hidden value is not present
|
||||
return if !$Data{UsedValue};
|
||||
|
||||
# set the correct return value
|
||||
my $Value = '0';
|
||||
if ( $Data{FieldValue} ) {
|
||||
$Value = $Data{FieldValue};
|
||||
}
|
||||
|
||||
return $Value;
|
||||
}
|
||||
|
||||
sub EditFieldValueValidate {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# get the field value from the http request
|
||||
my $FieldValue = $Self->EditFieldValueGet(
|
||||
DynamicFieldConfig => $Param{DynamicFieldConfig},
|
||||
ParamObject => $Param{ParamObject},
|
||||
|
||||
# not necessary for this backend but place it for consistency reasons
|
||||
ReturnValueStructure => 1,
|
||||
);
|
||||
my $Value = $FieldValue->{FieldValue} || '';
|
||||
|
||||
my $ServerError;
|
||||
my $ErrorMessage;
|
||||
|
||||
# perform necessary validations
|
||||
if ( $Param{Mandatory} && !$Value ) {
|
||||
$ServerError = 1;
|
||||
}
|
||||
|
||||
# validate only 0 or 1 as possible values
|
||||
if ( $Value && $Value ne 1 ) {
|
||||
$ServerError = 1;
|
||||
$ErrorMessage = 'The field content is invalid';
|
||||
}
|
||||
|
||||
# create resulting structure
|
||||
my $Result = {
|
||||
ServerError => $ServerError,
|
||||
ErrorMessage => $ErrorMessage,
|
||||
};
|
||||
|
||||
return $Result;
|
||||
}
|
||||
|
||||
sub DisplayValueRender {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check for Null value
|
||||
if ( !defined $Param{Value} ) {
|
||||
return {
|
||||
Value => '',
|
||||
Title => '',
|
||||
Link => '',
|
||||
};
|
||||
}
|
||||
|
||||
# convert value to user friendly string
|
||||
my $Value = 'Checked';
|
||||
if ( $Param{Value} ne 1 ) {
|
||||
$Value = 'Unchecked';
|
||||
}
|
||||
|
||||
# always translate value
|
||||
$Value = $Param{LayoutObject}->{LanguageObject}->Translate($Value);
|
||||
|
||||
# in this backend there is no need for HTMLOutput
|
||||
# Title is always equal to Value
|
||||
my $Title = $Value;
|
||||
|
||||
# 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};
|
||||
|
||||
my $Value;
|
||||
my @DefaultValue;
|
||||
|
||||
if ( defined $Param{DefaultValue} ) {
|
||||
@DefaultValue = split /;/, $Param{DefaultValue};
|
||||
}
|
||||
|
||||
# set the field value
|
||||
if (@DefaultValue) {
|
||||
$Value = \@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;
|
||||
}
|
||||
|
||||
for my $Item ( @{$Value} ) {
|
||||
|
||||
# value must be 1, '' or -1
|
||||
if ( !defined $Item || !$Item ) {
|
||||
$Item = '';
|
||||
}
|
||||
elsif ( $Item && $Item >= 1 ) {
|
||||
$Item = 1;
|
||||
}
|
||||
else {
|
||||
$Item = -1;
|
||||
}
|
||||
}
|
||||
|
||||
# check and set class if necessary
|
||||
my $FieldClass = 'DynamicFieldDropdown Modernize';
|
||||
|
||||
my $HTMLString = $Param{LayoutObject}->BuildSelection(
|
||||
Data => {
|
||||
1 => 'Checked',
|
||||
-1 => 'Unchecked',
|
||||
},
|
||||
Name => $FieldName,
|
||||
SelectedID => $Value || '',
|
||||
Translation => 1,
|
||||
PossibleNone => 1,
|
||||
Class => $FieldClass,
|
||||
Multiple => 1,
|
||||
HTMLQuote => 1,
|
||||
);
|
||||
|
||||
# call EditLabelRender on the common backend
|
||||
my $LabelString = $Self->EditLabelRender(
|
||||
%Param,
|
||||
FieldName => $FieldName,
|
||||
);
|
||||
|
||||
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} ) {
|
||||
my @FieldValues = $Param{ParamObject}->GetArray(
|
||||
Param => 'Search_DynamicField_' . $Param{DynamicFieldConfig}->{Name}
|
||||
);
|
||||
|
||||
$Value = \@FieldValues;
|
||||
}
|
||||
|
||||
# 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);
|
||||
|
||||
my $DisplayValue;
|
||||
|
||||
if ( defined $Value && !$Value ) {
|
||||
$DisplayValue = '';
|
||||
}
|
||||
|
||||
if ($Value) {
|
||||
|
||||
if ( ref $Value eq "ARRAY" ) {
|
||||
my @DisplayItemList;
|
||||
ITEM:
|
||||
for my $Item ( @{$Value} ) {
|
||||
|
||||
# set the display value
|
||||
my $DisplayItem = $Item eq 1
|
||||
? 'Checked'
|
||||
: $Item eq -1 ? 'Unchecked'
|
||||
: '';
|
||||
|
||||
# translate the value
|
||||
if ( defined $Param{LayoutObject} ) {
|
||||
$DisplayItem = $Param{LayoutObject}->{LanguageObject}->Translate($DisplayItem);
|
||||
}
|
||||
|
||||
push @DisplayItemList, $DisplayItem;
|
||||
|
||||
# set the correct value for "unchecked" (-1) search options
|
||||
if ( $Item && $Item eq -1 ) {
|
||||
$Item = '0';
|
||||
}
|
||||
}
|
||||
|
||||
# combine different values into one string
|
||||
$DisplayValue = join ' + ', @DisplayItemList;
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
# set the display value
|
||||
$DisplayValue = $Value eq 1
|
||||
? 'Checked'
|
||||
: $Value eq -1 ? 'Unchecked'
|
||||
: '';
|
||||
|
||||
# translate the value
|
||||
if ( defined $Param{LayoutObject} ) {
|
||||
$DisplayValue = $Param{LayoutObject}->{LanguageObject}->Translate($DisplayValue);
|
||||
}
|
||||
}
|
||||
|
||||
# set the correct value for "unchecked" (-1) search options
|
||||
if ( $Value && $Value eq -1 ) {
|
||||
$Value = '0';
|
||||
}
|
||||
}
|
||||
|
||||
# return search parameter structure
|
||||
return {
|
||||
Parameter => {
|
||||
Equals => $Value,
|
||||
},
|
||||
Display => $DisplayValue,
|
||||
};
|
||||
}
|
||||
|
||||
sub StatsFieldParameterBuild {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
return {
|
||||
Values => {
|
||||
'1' => 'Checked',
|
||||
'-1' => 'Unchecked',
|
||||
},
|
||||
Name => $Param{DynamicFieldConfig}->{Label},
|
||||
Element => 'DynamicField_' . $Param{DynamicFieldConfig}->{Name},
|
||||
TranslatableValues => 1,
|
||||
};
|
||||
}
|
||||
|
||||
sub StatsSearchFieldParameterBuild {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
my $Operator = 'Equals';
|
||||
my $Value = $Param{Value};
|
||||
|
||||
if ( IsArrayRefWithData($Value) ) {
|
||||
for my $Item ( @{$Value} ) {
|
||||
|
||||
# set the correct value for "unchecked" (-1) search options
|
||||
if ( $Item && $Item eq '-1' ) {
|
||||
$Item = '0';
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
# set the correct value for "unchecked" (-1) search options
|
||||
if ( $Value && $Value eq '-1' ) {
|
||||
$Value = '0';
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
$Operator => $Value,
|
||||
};
|
||||
}
|
||||
|
||||
sub ReadableValueRender {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
my $Value = defined $Param{Value} ? $Param{Value} : '';
|
||||
|
||||
# Title is always equal to Value
|
||||
my $Title = $Value;
|
||||
|
||||
# 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 = 'ARRAY';
|
||||
|
||||
# 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(2) );
|
||||
|
||||
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 => 'Integer',
|
||||
);
|
||||
|
||||
# return the historical values from database
|
||||
return $HistoricalValues;
|
||||
}
|
||||
|
||||
sub ValueLookup {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
return if !defined $Param{Key};
|
||||
|
||||
return '' if $Param{Key} eq '';
|
||||
|
||||
my $Value = defined $Param{Key} && $Param{Key} eq '1' ? 'Checked' : 'Unchecked';
|
||||
|
||||
# check if translation is possible
|
||||
if ( defined $Param{LanguageObject} ) {
|
||||
|
||||
# translate value
|
||||
$Value = $Param{LanguageObject}->Translate($Value);
|
||||
}
|
||||
|
||||
return $Value;
|
||||
}
|
||||
|
||||
sub ColumnFilterValuesGet {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# set PossibleValues
|
||||
my $SelectionData = {
|
||||
0 => 'Unchecked',
|
||||
1 => 'Checked',
|
||||
};
|
||||
|
||||
# get historical values from database
|
||||
my $ColumnFilterValues = $Kernel::OM->Get('Kernel::System::Ticket::ColumnFilter')->DynamicFieldFilterValuesGet(
|
||||
TicketIDs => $Param{TicketIDs},
|
||||
FieldID => $Param{DynamicFieldConfig}->{ID},
|
||||
ValueType => 'Integer',
|
||||
);
|
||||
|
||||
# get the display value if still exist in dynamic field configuration
|
||||
for my $Key ( sort keys %{$ColumnFilterValues} ) {
|
||||
if ( $SelectionData->{$Key} ) {
|
||||
$ColumnFilterValues->{$Key} = $SelectionData->{$Key};
|
||||
}
|
||||
}
|
||||
|
||||
# translate the value
|
||||
for my $ValueKey ( sort keys %{$ColumnFilterValues} ) {
|
||||
|
||||
my $OriginalValueName = $ColumnFilterValues->{$ValueKey};
|
||||
$ColumnFilterValues->{$ValueKey} = $Param{LayoutObject}->{LanguageObject}->Translate($OriginalValueName);
|
||||
}
|
||||
|
||||
return $ColumnFilterValues;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 TERMS AND CONDITIONS
|
||||
|
||||
This software is part of the OTRS project (L<https://otrs.org/>).
|
||||
|
||||
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<https://www.gnu.org/licenses/gpl-3.0.txt>.
|
||||
|
||||
=cut
|
||||
1346
Perl OTRS/Kernel/System/DynamicField/Driver/Date.pm
Normal file
1346
Perl OTRS/Kernel/System/DynamicField/Driver/Date.pm
Normal file
File diff suppressed because it is too large
Load Diff
110
Perl OTRS/Kernel/System/DynamicField/Driver/DateTime.pm
Normal file
110
Perl OTRS/Kernel/System/DynamicField/Driver/DateTime.pm
Normal file
@@ -0,0 +1,110 @@
|
||||
# --
|
||||
# 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::DateTime;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Kernel::System::VariableCheck qw(:all);
|
||||
|
||||
use parent qw(Kernel::System::DynamicField::Driver::BaseDateTime);
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::Config',
|
||||
'Kernel::System::DynamicFieldValue',
|
||||
'Kernel::System::Main',
|
||||
);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Kernel::System::DynamicField::Driver::DateTime
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
DynamicFields DateTime Driver delegate
|
||||
|
||||
=head1 PUBLIC INTERFACE
|
||||
|
||||
This module implements the public interface of L<Kernel::System::DynamicField::Backend>.
|
||||
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 field behaviors
|
||||
$Self->{Behaviors} = {
|
||||
'IsACLReducible' => 0,
|
||||
'IsNotificationEventCondition' => 0,
|
||||
'IsSortable' => 1,
|
||||
'IsFiltrable' => 0,
|
||||
'IsStatsCondition' => 1,
|
||||
'IsCustomerInterfaceCapable' => 1,
|
||||
};
|
||||
|
||||
# get the Dynamic Field Backend custom extensions
|
||||
my $DynamicFieldDriverExtensions
|
||||
= $Kernel::OM->Get('Kernel::Config')->Get('DynamicFields::Extension::Driver::DateTime');
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 TERMS AND CONDITIONS
|
||||
|
||||
This software is part of the OTRS project (L<https://otrs.org/>).
|
||||
|
||||
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<https://www.gnu.org/licenses/gpl-3.0.txt>.
|
||||
|
||||
=cut
|
||||
141
Perl OTRS/Kernel/System/DynamicField/Driver/Dropdown.pm
Normal file
141
Perl OTRS/Kernel/System/DynamicField/Driver/Dropdown.pm
Normal file
@@ -0,0 +1,141 @@
|
||||
# --
|
||||
# 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::Dropdown;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Kernel::System::VariableCheck qw(:all);
|
||||
|
||||
use parent qw(Kernel::System::DynamicField::Driver::BaseSelect);
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::Config',
|
||||
'Kernel::System::DynamicFieldValue',
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::Main',
|
||||
);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Kernel::System::DynamicField::Driver::Dropdown
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
DynamicFields Dropdown Driver delegate
|
||||
|
||||
=head1 PUBLIC INTERFACE
|
||||
|
||||
This module implements the public interface of L<Kernel::System::DynamicField::Backend>.
|
||||
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 field behaviors
|
||||
$Self->{Behaviors} = {
|
||||
'IsACLReducible' => 1,
|
||||
'IsNotificationEventCondition' => 1,
|
||||
'IsSortable' => 1,
|
||||
'IsFiltrable' => 1,
|
||||
'IsStatsCondition' => 1,
|
||||
'IsCustomerInterfaceCapable' => 1,
|
||||
'IsLikeOperatorCapable' => 1,
|
||||
};
|
||||
|
||||
# get the Dynamic Field Backend custom extensions
|
||||
my $DynamicFieldDriverExtensions
|
||||
= $Kernel::OM->Get('Kernel::Config')->Get('DynamicFields::Extension::Driver::Dropdown');
|
||||
|
||||
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 FieldValueValidate {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# Check for valid possible values list.
|
||||
if ( !IsHashRefWithData( $Param{DynamicFieldConfig}->{Config}->{PossibleValues} ) ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need PossibleValues in Dropdown DynamicFieldConfig!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# Check for defined value.
|
||||
if ( !defined $Param{Value} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need Value in Dropdown DynamicField!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# Check if value parameter exists in possible values config.
|
||||
if ( length $Param{Value} ) {
|
||||
return if !$Param{DynamicFieldConfig}->{Config}->{PossibleValues}->{ $Param{Value} };
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 TERMS AND CONDITIONS
|
||||
|
||||
This software is part of the OTRS project (L<https://otrs.org/>).
|
||||
|
||||
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<https://www.gnu.org/licenses/gpl-3.0.txt>.
|
||||
|
||||
=cut
|
||||
696
Perl OTRS/Kernel/System/DynamicField/Driver/MasterSlave.pm
Normal file
696
Perl OTRS/Kernel/System/DynamicField/Driver/MasterSlave.pm
Normal file
@@ -0,0 +1,696 @@
|
||||
# --
|
||||
# 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::MasterSlave;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Kernel::System::VariableCheck qw(:all);
|
||||
|
||||
use parent qw(Kernel::System::DynamicField::Driver::BaseSelect);
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::Config',
|
||||
'Kernel::Language',
|
||||
'Kernel::Output::HTML::Layout',
|
||||
'Kernel::System::DynamicFieldValue',
|
||||
'Kernel::System::LinkObject',
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::Main',
|
||||
'Kernel::System::Ticket',
|
||||
);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Kernel::System::DynamicField::Driver::MasterSlave
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
DynamicFields MasterSlave Driver delegate
|
||||
|
||||
=head1 PUBLIC INTERFACE
|
||||
|
||||
This module implements the public interface of L<Kernel::System::DynamicField::Backend>.
|
||||
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 field behaviors
|
||||
$Self->{Behaviors} = {
|
||||
'IsACLReducible' => 0,
|
||||
'IsNotificationEventCondition' => 1,
|
||||
'IsSortable' => 1,
|
||||
'IsFiltrable' => 1,
|
||||
'IsStatsCondition' => 1,
|
||||
'IsCustomerInterfaceCapable' => 0,
|
||||
};
|
||||
|
||||
# get the Dynamic Field Backend custom extensions
|
||||
my $DynamicFieldDriverExtensions
|
||||
= $Kernel::OM->Get('Kernel::Config')->Get('DynamicFields::Extension::Driver::MasterSlave');
|
||||
|
||||
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 ValueSet {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
my $Success = $Self->_HandleLinks(
|
||||
FieldName => $Param{DynamicFieldConfig}->{Name},
|
||||
FieldValue => $Param{Value},
|
||||
TicketID => $Param{ObjectID},
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
if ( !$Success ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "There was an error handling the links for master/slave, value could not be set",
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
my $Value = $Param{Value} !~ /^(?:UnsetMaster|UnsetSlave)$/ ? $Param{Value} : '';
|
||||
|
||||
$Success = $Kernel::OM->Get('Kernel::System::DynamicFieldValue')->ValueSet(
|
||||
FieldID => $Param{DynamicFieldConfig}->{ID},
|
||||
ObjectID => $Param{ObjectID},
|
||||
Value => [
|
||||
{
|
||||
ValueText => $Value,
|
||||
},
|
||||
],
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
return $Success;
|
||||
}
|
||||
|
||||
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 ) {
|
||||
return {
|
||||
ServerError => 1,
|
||||
};
|
||||
}
|
||||
else {
|
||||
|
||||
my $PossibleValues;
|
||||
|
||||
# use PossibleValuesFilter if sent
|
||||
if ( defined $Param{PossibleValuesFilter} ) {
|
||||
$PossibleValues = $Param{PossibleValuesFilter};
|
||||
}
|
||||
else {
|
||||
|
||||
# get possible values list
|
||||
$PossibleValues = $Self->PossibleValuesGet(
|
||||
%Param,
|
||||
);
|
||||
}
|
||||
|
||||
# validate if value is in possible values list (but let pass empty values)
|
||||
if ( $Value && !$PossibleValues->{$Value} ) {
|
||||
$ServerError = 1;
|
||||
$ErrorMessage = 'The field content is invalid';
|
||||
}
|
||||
}
|
||||
|
||||
# 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 Value strings from field value
|
||||
my $Value = defined $Param{Value} ? $Param{Value} : '';
|
||||
|
||||
# get real value
|
||||
if ( $Param{DynamicFieldConfig}->{Config}->{PossibleValues}->{$Value} ) {
|
||||
|
||||
# get readable value
|
||||
$Value = $Param{DynamicFieldConfig}->{Config}->{PossibleValues}->{$Value};
|
||||
}
|
||||
|
||||
if ( $Value eq 'Master' ) {
|
||||
$Value = $Param{LayoutObject}->{LanguageObject}->Translate('Master');
|
||||
}
|
||||
elsif ( $Value =~ m{SlaveOf:(\d+)}msx ) {
|
||||
|
||||
my $TicketNumber = $1;
|
||||
if ($TicketNumber) {
|
||||
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
|
||||
my $TicketHook = $ConfigObject->Get('Ticket::Hook');
|
||||
my $TicketHookDivider = $ConfigObject->Get('Ticket::HookDivider');
|
||||
$Value = $Param{LayoutObject}->{LanguageObject}->Translate(
|
||||
'Slave of %s%s%s',
|
||||
$TicketHook,
|
||||
$TicketHookDivider,
|
||||
$TicketNumber,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
# set title as value after update and before limit
|
||||
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 from config
|
||||
my $Link = $Param{DynamicFieldConfig}->{Config}->{Link} || '';
|
||||
my $LinkPreview = $Param{DynamicFieldConfig}->{Config}->{LinkPreview} || '';
|
||||
|
||||
my $Data = {
|
||||
Value => $Value,
|
||||
Title => $Title,
|
||||
Link => $Link,
|
||||
LinkPreview => $LinkPreview,
|
||||
};
|
||||
|
||||
return $Data;
|
||||
}
|
||||
|
||||
sub PossibleValuesGet {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# to store the possible values
|
||||
my %PossibleValues = (
|
||||
'' => '-',
|
||||
);
|
||||
|
||||
# get needed objects
|
||||
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
|
||||
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
|
||||
|
||||
# find all current open master slave tickets
|
||||
my @TicketIDs = $TicketObject->TicketSearch(
|
||||
Result => 'ARRAY',
|
||||
|
||||
# master slave dynamic field
|
||||
'DynamicField_' . $Param{DynamicFieldConfig}->{Name} => {
|
||||
Equals => 'Master',
|
||||
},
|
||||
|
||||
StateType => 'Open',
|
||||
Limit => 60,
|
||||
UserID => $LayoutObject->{UserID},
|
||||
Permission => 'ro',
|
||||
);
|
||||
|
||||
# set dynamic field possible values
|
||||
$PossibleValues{Master} = $LayoutObject->{LanguageObject}->Translate('New Master Ticket');
|
||||
|
||||
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
|
||||
my $TicketHook = $ConfigObject->Get('Ticket::Hook');
|
||||
my $TicketHookDivider = $ConfigObject->Get('Ticket::HookDivider');
|
||||
|
||||
TICKET:
|
||||
for my $TicketID (@TicketIDs) {
|
||||
my %CurrentTicket = $TicketObject->TicketGet(
|
||||
TicketID => $TicketID,
|
||||
DynamicFields => 1,
|
||||
);
|
||||
|
||||
next TICKET if !%CurrentTicket;
|
||||
|
||||
# set dynamic field possible values
|
||||
$PossibleValues{"SlaveOf:$CurrentTicket{TicketNumber}"} = $LayoutObject->{LanguageObject}->Translate(
|
||||
'Slave of %s%s%s: %s',
|
||||
$TicketHook,
|
||||
$TicketHookDivider,
|
||||
$CurrentTicket{TicketNumber},
|
||||
$CurrentTicket{Title},
|
||||
);
|
||||
}
|
||||
|
||||
# return the possible values hash as a reference
|
||||
return \%PossibleValues;
|
||||
}
|
||||
|
||||
sub _HandleLinks {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
for my $Needed (qw(FieldName FieldValue TicketID UserID)) {
|
||||
if ( !$Param{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# get ticket object
|
||||
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
|
||||
|
||||
my $FieldName = $Param{FieldName};
|
||||
|
||||
my %Ticket = $Param{Ticket}
|
||||
? %{ $Param{Ticket} }
|
||||
: $TicketObject->TicketGet(
|
||||
TicketID => $Param{TicketID},
|
||||
DynamicFields => 1,
|
||||
);
|
||||
|
||||
my $OldValue = $Ticket{ 'DynamicField_' . $FieldName };
|
||||
|
||||
# get config object
|
||||
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
|
||||
|
||||
# get master slave config
|
||||
my $MasterSlaveKeepParentChildAfterUnset = $ConfigObject->Get('MasterSlave::KeepParentChildAfterUnset') || 0;
|
||||
my $MasterSlaveFollowUpdatedMaster = $ConfigObject->Get('MasterSlave::FollowUpdatedMaster') || 0;
|
||||
my $MasterSlaveKeepParentChildAfterUpdate = $ConfigObject->Get('MasterSlave::KeepParentChildAfterUpdate') || 0;
|
||||
|
||||
my $NewValue = $Param{FieldValue};
|
||||
|
||||
# get link object
|
||||
my $LinkObject = $Kernel::OM->Get('Kernel::System::LinkObject');
|
||||
|
||||
# set a new master ticket
|
||||
# check if it is already a master ticket
|
||||
if (
|
||||
$NewValue eq 'Master'
|
||||
&& ( !$OldValue || $OldValue ne $NewValue )
|
||||
)
|
||||
{
|
||||
|
||||
# check if it was a slave ticket before and if we have to delete
|
||||
# the old parent child link (MasterSlaveKeepParentChildAfterUnset)
|
||||
if (
|
||||
$OldValue
|
||||
&& $OldValue =~ /^SlaveOf:(.*?)$/
|
||||
&& !$MasterSlaveKeepParentChildAfterUnset
|
||||
)
|
||||
{
|
||||
my $SourceKey = $TicketObject->TicketIDLookup(
|
||||
TicketNumber => $1,
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
$LinkObject->LinkDelete(
|
||||
Object1 => 'Ticket',
|
||||
Key1 => $SourceKey,
|
||||
Object2 => 'Ticket',
|
||||
Key2 => $Param{TicketID},
|
||||
Type => 'ParentChild',
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
# set a new slave ticket
|
||||
# check if it's already the slave of the wished master ticket
|
||||
elsif (
|
||||
$NewValue =~ /^SlaveOf:(.*?)$/
|
||||
&& ( !$OldValue || $OldValue ne $NewValue )
|
||||
)
|
||||
{
|
||||
my $SourceKey = $TicketObject->TicketIDLookup(
|
||||
TicketNumber => $1,
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
$LinkObject->LinkAdd(
|
||||
SourceObject => 'Ticket',
|
||||
SourceKey => $SourceKey,
|
||||
TargetObject => 'Ticket',
|
||||
TargetKey => $Param{TicketID},
|
||||
Type => 'ParentChild',
|
||||
State => 'Valid',
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
my %Links = $LinkObject->LinkKeyList(
|
||||
Object1 => 'Ticket',
|
||||
Key1 => $Param{TicketID},
|
||||
Object2 => 'Ticket',
|
||||
State => 'Valid',
|
||||
Type => 'ParentChild', # (optional)
|
||||
Direction => 'Target', # (optional) default Both (Source|Target|Both)
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
my @SlaveTicketIDs;
|
||||
|
||||
LINKEDTICKETID:
|
||||
for my $LinkedTicketID ( sort keys %Links ) {
|
||||
next LINKEDTICKETID if !$Links{$LinkedTicketID};
|
||||
|
||||
# just take ticket with slave attributes for action
|
||||
my %LinkedTicket = $TicketObject->TicketGet(
|
||||
TicketID => $LinkedTicketID,
|
||||
DynamicFields => 1,
|
||||
);
|
||||
|
||||
my $LinkedTicketValue = $Ticket{ 'DynamicField_' . $FieldName };
|
||||
|
||||
next LINKEDTICKETID if !$LinkedTicketValue;
|
||||
next LINKEDTICKETID if $LinkedTicketValue !~ /^SlaveOf:(.*?)$/;
|
||||
|
||||
# remember linked ticket id
|
||||
push @SlaveTicketIDs, $LinkedTicketID;
|
||||
}
|
||||
|
||||
if ( $OldValue && $OldValue eq 'Master' ) {
|
||||
|
||||
if ( $MasterSlaveFollowUpdatedMaster && @SlaveTicketIDs ) {
|
||||
for my $LinkedTicketID (@SlaveTicketIDs) {
|
||||
$LinkObject->LinkAdd(
|
||||
SourceObject => 'Ticket',
|
||||
SourceKey => $SourceKey,
|
||||
TargetObject => 'Ticket',
|
||||
TargetKey => $LinkedTicketID,
|
||||
Type => 'ParentChild',
|
||||
State => 'Valid',
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( !$MasterSlaveKeepParentChildAfterUnset ) {
|
||||
for my $LinkedTicketID (@SlaveTicketIDs) {
|
||||
$LinkObject->LinkDelete(
|
||||
Object1 => 'Ticket',
|
||||
Key1 => $Param{TicketID},
|
||||
Object2 => 'Ticket',
|
||||
Key2 => $LinkedTicketID,
|
||||
Type => 'ParentChild',
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif (
|
||||
$OldValue
|
||||
&& $OldValue =~ /^SlaveOf:(.*?)$/
|
||||
&& !$MasterSlaveKeepParentChildAfterUpdate
|
||||
)
|
||||
{
|
||||
my $SourceKey = $TicketObject->TicketIDLookup(
|
||||
TicketNumber => $1,
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
$LinkObject->LinkDelete(
|
||||
Object1 => 'Ticket',
|
||||
Key1 => $SourceKey,
|
||||
Object2 => 'Ticket',
|
||||
Key2 => $Param{TicketID},
|
||||
Type => 'ParentChild',
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
}
|
||||
}
|
||||
elsif ( $NewValue =~ /^(?:UnsetMaster|UnsetSlave)$/ && $OldValue ) {
|
||||
|
||||
if ( $NewValue eq 'UnsetMaster' && !$MasterSlaveKeepParentChildAfterUnset ) {
|
||||
my %Links = $LinkObject->LinkKeyList(
|
||||
Object1 => 'Ticket',
|
||||
Key1 => $Param{TicketID},
|
||||
Object2 => 'Ticket',
|
||||
State => 'Valid',
|
||||
Type => 'ParentChild', # (optional)
|
||||
Direction => 'Target', # (optional) default Both (Source|Target|Both)
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
my @SlaveTicketIDs;
|
||||
|
||||
LINKEDTICKETID:
|
||||
for my $LinkedTicketID ( sort keys %Links ) {
|
||||
next LINKEDTICKETID if !$Links{$LinkedTicketID};
|
||||
|
||||
# just take ticket with slave attributes for action
|
||||
my %LinkedTicket = $TicketObject->TicketGet(
|
||||
TicketID => $LinkedTicketID,
|
||||
DynamicFields => 1,
|
||||
);
|
||||
|
||||
my $LinkedTicketValue = $Ticket{ 'DynamicField_' . $FieldName };
|
||||
next LINKEDTICKETID if !$LinkedTicketValue;
|
||||
next LINKEDTICKETID if $LinkedTicketValue !~ /^SlaveOf:(.*?)$/;
|
||||
|
||||
# remember ticket id
|
||||
push @SlaveTicketIDs, $LinkedTicketID;
|
||||
}
|
||||
|
||||
for my $LinkedTicketID (@SlaveTicketIDs) {
|
||||
$LinkObject->LinkDelete(
|
||||
Object1 => 'Ticket',
|
||||
Key1 => $Param{TicketID},
|
||||
Object2 => 'Ticket',
|
||||
Key2 => $LinkedTicketID,
|
||||
Type => 'ParentChild',
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
}
|
||||
}
|
||||
elsif (
|
||||
$NewValue eq 'UnsetSlave'
|
||||
&& !$MasterSlaveKeepParentChildAfterUnset
|
||||
&& $OldValue =~ /^SlaveOf:(.*?)$/
|
||||
)
|
||||
{
|
||||
my $SourceKey = $TicketObject->TicketIDLookup(
|
||||
TicketNumber => $1,
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
$LinkObject->LinkDelete(
|
||||
Object1 => 'Ticket',
|
||||
Key1 => $SourceKey,
|
||||
Object2 => 'Ticket',
|
||||
Key2 => $Param{TicketID},
|
||||
Type => 'ParentChild',
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
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};
|
||||
|
||||
my $Value;
|
||||
|
||||
my @DefaultValue;
|
||||
|
||||
if ( defined $Param{DefaultValue} ) {
|
||||
@DefaultValue = split /;/, $Param{DefaultValue};
|
||||
}
|
||||
|
||||
# set the field value
|
||||
if (@DefaultValue) {
|
||||
$Value = \@DefaultValue;
|
||||
}
|
||||
|
||||
# get the field value, this function is always called after the profile is loaded
|
||||
my $FieldValues = $Self->SearchFieldValueGet(
|
||||
%Param,
|
||||
);
|
||||
|
||||
if ( defined $FieldValues ) {
|
||||
$Value = $FieldValues;
|
||||
}
|
||||
|
||||
# check and set class if necessary
|
||||
my $FieldClass = 'DynamicFieldMultiSelect Modernize';
|
||||
|
||||
# set TreeView class
|
||||
if ( $FieldConfig->{TreeView} ) {
|
||||
$FieldClass .= ' DynamicFieldWithTreeView';
|
||||
}
|
||||
|
||||
my $LanguageObject = $Kernel::OM->Get('Kernel::Language');
|
||||
|
||||
# set PossibleValues (master should be always an option)
|
||||
my $SelectionData = {
|
||||
Master => $LanguageObject->Translate('Master Ticket'),
|
||||
};
|
||||
|
||||
# get historical values from database
|
||||
my $HistoricalValues = $Self->HistoricalValuesGet(%Param);
|
||||
|
||||
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
|
||||
|
||||
if ( IsHashRefWithData($HistoricalValues) ) {
|
||||
|
||||
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
|
||||
my $TicketHook = $ConfigObject->Get('Ticket::Hook');
|
||||
my $TicketHookDivider = $ConfigObject->Get('Ticket::HookDivider');
|
||||
|
||||
# Recreate the display value from the already set tickets.
|
||||
VALUE:
|
||||
for my $ValueKey ( sort keys %{$HistoricalValues} ) {
|
||||
|
||||
if ( $ValueKey =~ m{SlaveOf:(.*)}gmx ) {
|
||||
my $TicketNumber = $1;
|
||||
|
||||
my $TicketID = $TicketObject->TicketIDLookup(
|
||||
TicketNumber => $TicketNumber,
|
||||
UserID => 1,
|
||||
);
|
||||
|
||||
my %Ticket;
|
||||
if ($TicketID) {
|
||||
%Ticket = $TicketObject->TicketGet(
|
||||
TicketID => $TicketID
|
||||
);
|
||||
}
|
||||
|
||||
next VALUE if !%Ticket;
|
||||
|
||||
$SelectionData->{$ValueKey} = $LanguageObject->Translate(
|
||||
'Slave of %s%s%s: %s',
|
||||
$TicketHook,
|
||||
$TicketHookDivider,
|
||||
$Ticket{TicketNumber},
|
||||
$Ticket{Title},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# use PossibleValuesFilter if defined
|
||||
$SelectionData = $Param{PossibleValuesFilter} // $SelectionData;
|
||||
|
||||
my $HTMLString = $Param{LayoutObject}->BuildSelection(
|
||||
Data => $SelectionData,
|
||||
Name => $FieldName,
|
||||
SelectedID => $Value,
|
||||
Translation => 0,
|
||||
PossibleNone => 0,
|
||||
Class => $FieldClass,
|
||||
Multiple => 1,
|
||||
HTMLQuote => 1,
|
||||
);
|
||||
|
||||
# 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<https://otrs.org/>).
|
||||
|
||||
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<https://www.gnu.org/licenses/gpl-3.0.txt>.
|
||||
|
||||
=cut
|
||||
1048
Perl OTRS/Kernel/System/DynamicField/Driver/Multiselect.pm
Normal file
1048
Perl OTRS/Kernel/System/DynamicField/Driver/Multiselect.pm
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,277 @@
|
||||
# --
|
||||
# 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::ProcessManagement::ActivityID;
|
||||
|
||||
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',
|
||||
'Kernel::System::ProcessManagement::Activity',
|
||||
'Kernel::System::ProcessManagement::DB::Activity',
|
||||
'Kernel::System::Ticket::ColumnFilter',
|
||||
);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Kernel::System::DynamicField::Driver::ProcessManagement::ActivityID
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
DynamicFields Text Driver delegate
|
||||
|
||||
=head1 PUBLIC INTERFACE
|
||||
|
||||
This module implements the public interface of L<Kernel::System::DynamicField::Backend>.
|
||||
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 field behaviors
|
||||
$Self->{Behaviors} = {
|
||||
'IsACLReducible' => 0,
|
||||
'IsNotificationEventCondition' => 1,
|
||||
'IsSortable' => 1,
|
||||
'IsFiltrable' => 1,
|
||||
'IsStatsCondition' => 1,
|
||||
'IsCustomerInterfaceCapable' => 1,
|
||||
};
|
||||
|
||||
# get the Dynamic Field Backend custom extensions
|
||||
my $DynamicFieldDriverExtensions
|
||||
= $Kernel::OM->Get('Kernel::Config')->Get('DynamicFields::Extension::Driver::Text');
|
||||
|
||||
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 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
|
||||
# convert the ActivityEntityID to the Activity name
|
||||
my $Activity;
|
||||
if ( $Param{Value} ) {
|
||||
$Activity = $Kernel::OM->Get('Kernel::System::ProcessManagement::Activity')->ActivityGet(
|
||||
ActivityEntityID => $Param{Value},
|
||||
Interface => 'all',
|
||||
);
|
||||
}
|
||||
my $Value = $Activity->{Name} // '';
|
||||
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} || '';
|
||||
|
||||
# create return structure
|
||||
my $Data = {
|
||||
Value => $Value,
|
||||
Title => $Title,
|
||||
Link => $Link,
|
||||
};
|
||||
|
||||
return $Data;
|
||||
}
|
||||
|
||||
sub ColumnFilterValuesGet {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# take config from field config
|
||||
my $FieldConfig = $Param{DynamicFieldConfig}->{Config};
|
||||
|
||||
# set PossibleValues
|
||||
my $SelectionData = $Kernel::OM->Get('Kernel::System::ProcessManagement::Activity')->ActivityList();
|
||||
|
||||
# get column filter values from database
|
||||
my $ColumnFilterValues = $Kernel::OM->Get('Kernel::System::Ticket::ColumnFilter')->DynamicFieldFilterValuesGet(
|
||||
TicketIDs => $Param{TicketIDs},
|
||||
FieldID => $Param{DynamicFieldConfig}->{ID},
|
||||
ValueType => 'Text',
|
||||
);
|
||||
|
||||
# get the display value if still exist in dynamic field configuration
|
||||
for my $Key ( sort keys %{$ColumnFilterValues} ) {
|
||||
if ( $SelectionData->{$Key} ) {
|
||||
$ColumnFilterValues->{$Key} = $SelectionData->{$Key};
|
||||
}
|
||||
}
|
||||
|
||||
return $ColumnFilterValues;
|
||||
}
|
||||
|
||||
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';
|
||||
}
|
||||
|
||||
if ( $Param{DynamicFieldConfig}->{Name} eq 'ProcessManagementActivityID' && $Value ) {
|
||||
|
||||
my $ActivityEntityIDs = $Kernel::OM->Get('Kernel::System::ProcessManagement::DB::Activity')->ActivitySearch(
|
||||
ActivityName => $Value,
|
||||
);
|
||||
|
||||
if ( IsArrayRefWithData($ActivityEntityIDs) ) {
|
||||
|
||||
# Add search term from input field.
|
||||
push @{$ActivityEntityIDs}, $Value;
|
||||
|
||||
# Return search parameter structure.
|
||||
return {
|
||||
Parameter => {
|
||||
$Operator => $ActivityEntityIDs,
|
||||
},
|
||||
Display => $Value,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
# Return search parameter structure.
|
||||
return {
|
||||
Parameter => {
|
||||
$Operator => $Value,
|
||||
},
|
||||
Display => $Value,
|
||||
};
|
||||
}
|
||||
|
||||
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';
|
||||
}
|
||||
|
||||
if ( $Param{DynamicFieldConfig}->{Name} eq 'ProcessManagementActivityID' && $Value ) {
|
||||
|
||||
my $ActivityEntityIDs = $Kernel::OM->Get('Kernel::System::ProcessManagement::DB::Activity')->ActivitySearch(
|
||||
ActivityName => $Value,
|
||||
);
|
||||
|
||||
if ( IsArrayRefWithData($ActivityEntityIDs) ) {
|
||||
|
||||
# Add search term from input field.
|
||||
push @{$ActivityEntityIDs}, $Value;
|
||||
|
||||
# Return search parameter structure.
|
||||
return {
|
||||
$Operator => $ActivityEntityIDs,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
$Operator => $Value,
|
||||
};
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 TERMS AND CONDITIONS
|
||||
|
||||
This software is part of the OTRS project (L<https://otrs.org/>).
|
||||
|
||||
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<https://www.gnu.org/licenses/gpl-3.0.txt>.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,284 @@
|
||||
# --
|
||||
# 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::ProcessManagement::ProcessID;
|
||||
|
||||
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',
|
||||
'Kernel::System::ProcessManagement::Process',
|
||||
'Kernel::System::ProcessManagement::DB::Process',
|
||||
'Kernel::System::Ticket::ColumnFilter',
|
||||
);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Kernel::System::DynamicField::Driver::ProcessManagement::ProcessID
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
DynamicFields Text Driver delegate
|
||||
|
||||
=head1 PUBLIC INTERFACE
|
||||
|
||||
This module implements the public interface of L<Kernel::System::DynamicField::Backend>.
|
||||
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 field behaviors
|
||||
$Self->{Behaviors} = {
|
||||
'IsACLReducible' => 0,
|
||||
'IsNotificationEventCondition' => 1,
|
||||
'IsSortable' => 1,
|
||||
'IsFiltrable' => 1,
|
||||
'IsStatsCondition' => 1,
|
||||
'IsCustomerInterfaceCapable' => 1,
|
||||
};
|
||||
|
||||
# get the Dynamic Field Backend custom extensions
|
||||
my $DynamicFieldDriverExtensions
|
||||
= $Kernel::OM->Get('Kernel::Config')->Get('DynamicFields::Extension::Driver::Text');
|
||||
|
||||
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 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
|
||||
# convert the ProcessEntityID to the Process name
|
||||
my $Process;
|
||||
if ( $Param{Value} ) {
|
||||
$Process = $Kernel::OM->Get('Kernel::System::ProcessManagement::Process')->ProcessGet(
|
||||
ProcessEntityID => $Param{Value},
|
||||
);
|
||||
}
|
||||
|
||||
my $Value = $Process->{Name} // '';
|
||||
|
||||
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} || '';
|
||||
|
||||
# create return structure
|
||||
my $Data = {
|
||||
Value => $Value,
|
||||
Title => $Title,
|
||||
Link => $Link,
|
||||
};
|
||||
|
||||
return $Data;
|
||||
}
|
||||
|
||||
sub ColumnFilterValuesGet {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# take config from field config
|
||||
my $FieldConfig = $Param{DynamicFieldConfig}->{Config};
|
||||
|
||||
# set PossibleValues
|
||||
my $SelectionData = $Kernel::OM->Get('Kernel::System::ProcessManagement::Process')->ProcessList(
|
||||
ProcessState => [ 'Active', 'FadeAway', 'Inactive' ],
|
||||
Interface => 'all',
|
||||
);
|
||||
|
||||
# get column filter values from database
|
||||
my $ColumnFilterValues = $Kernel::OM->Get('Kernel::System::Ticket::ColumnFilter')->DynamicFieldFilterValuesGet(
|
||||
TicketIDs => $Param{TicketIDs},
|
||||
FieldID => $Param{DynamicFieldConfig}->{ID},
|
||||
ValueType => 'Text',
|
||||
);
|
||||
|
||||
# get the display value if still exist in dynamic field configuration
|
||||
for my $Key ( sort keys %{$ColumnFilterValues} ) {
|
||||
if ( $SelectionData->{$Key} ) {
|
||||
$ColumnFilterValues->{$Key} = $SelectionData->{$Key};
|
||||
}
|
||||
}
|
||||
|
||||
return $ColumnFilterValues;
|
||||
}
|
||||
|
||||
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';
|
||||
}
|
||||
|
||||
if ( $Param{DynamicFieldConfig}->{Name} eq 'ProcessManagementProcessID' && $Value ) {
|
||||
|
||||
my $ProcessEntityIDs = $Kernel::OM->Get('Kernel::System::ProcessManagement::DB::Process')->ProcessSearch(
|
||||
ProcessName => $Value,
|
||||
);
|
||||
|
||||
if ( IsArrayRefWithData($ProcessEntityIDs) ) {
|
||||
|
||||
# Add search term from input field.
|
||||
push @{$ProcessEntityIDs}, $Value;
|
||||
|
||||
# Return search parameter structure.
|
||||
return {
|
||||
Parameter => {
|
||||
$Operator => $ProcessEntityIDs,
|
||||
},
|
||||
Display => $Value,
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# Return search parameter structure.
|
||||
return {
|
||||
Parameter => {
|
||||
$Operator => $Value,
|
||||
},
|
||||
Display => $Value,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
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';
|
||||
}
|
||||
|
||||
if ( $Param{DynamicFieldConfig}->{Name} eq 'ProcessManagementProcessID' && $Value ) {
|
||||
|
||||
my $ProcessEntityIDs = $Kernel::OM->Get('Kernel::System::ProcessManagement::DB::Process')->ProcessSearch(
|
||||
ProcessName => $Value,
|
||||
);
|
||||
|
||||
if ( IsArrayRefWithData($ProcessEntityIDs) ) {
|
||||
|
||||
# Add search term from input field.
|
||||
push @{$ProcessEntityIDs}, $Value;
|
||||
|
||||
# Return search parameter structure.
|
||||
return {
|
||||
$Operator => $ProcessEntityIDs,
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
$Operator => $Value,
|
||||
};
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 TERMS AND CONDITIONS
|
||||
|
||||
This software is part of the OTRS project (L<https://otrs.org/>).
|
||||
|
||||
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<https://www.gnu.org/licenses/gpl-3.0.txt>.
|
||||
|
||||
=cut
|
||||
111
Perl OTRS/Kernel/System/DynamicField/Driver/Text.pm
Normal file
111
Perl OTRS/Kernel/System/DynamicField/Driver/Text.pm
Normal file
@@ -0,0 +1,111 @@
|
||||
# --
|
||||
# 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::Text;
|
||||
|
||||
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::Text
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
DynamicFields Text Driver delegate
|
||||
|
||||
=head1 PUBLIC INTERFACE
|
||||
|
||||
This module implements the public interface of L<Kernel::System::DynamicField::Backend>.
|
||||
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 field behaviors
|
||||
$Self->{Behaviors} = {
|
||||
'IsACLReducible' => 0,
|
||||
'IsNotificationEventCondition' => 1,
|
||||
'IsSortable' => 1,
|
||||
'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::Text');
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 TERMS AND CONDITIONS
|
||||
|
||||
This software is part of the OTRS project (L<https://otrs.org/>).
|
||||
|
||||
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<https://www.gnu.org/licenses/gpl-3.0.txt>.
|
||||
|
||||
=cut
|
||||
396
Perl OTRS/Kernel/System/DynamicField/Driver/TextArea.pm
Normal file
396
Perl OTRS/Kernel/System/DynamicField/Driver/TextArea.pm
Normal file
@@ -0,0 +1,396 @@
|
||||
# --
|
||||
# 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<Kernel::System::DynamicField::Backend>.
|
||||
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";
|
||||
<textarea class="$FieldClass" id="$FieldName" name="$FieldName" title="$FieldLabelEscaped" rows="$RowsNumber" cols="$ColsNumber" data-maxlength="$MaxLength">$ValueEscaped</textarea>
|
||||
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";
|
||||
<div id="$DivID" class="TooltipErrorMessage">
|
||||
<p>
|
||||
$ErrorMessage1 $ErrorMessage2 $ErrorMessage3
|
||||
</p>
|
||||
</div>
|
||||
EOF
|
||||
}
|
||||
else {
|
||||
$HTMLString .= <<"EOF";
|
||||
<div id="$DivID" class="TooltipErrorMessage">
|
||||
<p>
|
||||
$ErrorMessage2 $ErrorMessage3
|
||||
</p>
|
||||
</div>
|
||||
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";
|
||||
<div id="$DivID" class="TooltipErrorMessage">
|
||||
<p>
|
||||
$ErrorMessage
|
||||
</p>
|
||||
</div>
|
||||
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";
|
||||
<input type="text" class="$FieldClass" id="$FieldName" name="$FieldName" title="$FieldLabelEscaped" value="$ValueEscaped" />
|
||||
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<https://otrs.org/>).
|
||||
|
||||
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<https://www.gnu.org/licenses/gpl-3.0.txt>.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,157 @@
|
||||
# --
|
||||
# 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::Event::UpdateITSMChangeConditions;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Kernel::System::VariableCheck qw(:all);
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::System::Cache',
|
||||
'Kernel::System::DB',
|
||||
'Kernel::System::ITSMChange::ITSMCondition',
|
||||
'Kernel::System::Log',
|
||||
);
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
sub Run {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
for my $Argument (qw(Data Event Config UserID)) {
|
||||
if ( !$Param{$Argument} ) {
|
||||
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Argument!",
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# only for dynamic fields of the type ITSMChange or ITSMWorkOrder
|
||||
return if !$Param{Data}->{NewData};
|
||||
return if !$Param{Data}->{NewData}->{ObjectType};
|
||||
if (
|
||||
$Param{Data}->{NewData}->{ObjectType} ne 'ITSMChange'
|
||||
&& $Param{Data}->{NewData}->{ObjectType} ne 'ITSMWorkOrder'
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
# dynamic field has been added
|
||||
if ( $Param{Event} eq 'DynamicFieldAdd' ) {
|
||||
|
||||
# add new attribute to condition attribute table
|
||||
my $Success = $Kernel::OM->Get('Kernel::System::ITSMChange::ITSMCondition')->AttributeAdd(
|
||||
Name => 'DynamicField_' . $Param{Data}->{NewData}->{Name},
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
# check error
|
||||
if ( !$Success ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message =>
|
||||
"Could not add attribute '$Param{Data}->{NewData}->{Name}' to condition attribute table!",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
# dynamic field has been updated
|
||||
elsif ( $Param{Event} eq 'DynamicFieldUpdate' ) {
|
||||
|
||||
# lookup the ID of the old attribute
|
||||
my $AttributeID = $Kernel::OM->Get('Kernel::System::ITSMChange::ITSMCondition')->AttributeLookup(
|
||||
Name => 'DynamicField_' . $Param{Data}->{OldData}->{Name},
|
||||
);
|
||||
|
||||
# update the attribute name
|
||||
my $Success = $Kernel::OM->Get('Kernel::System::ITSMChange::ITSMCondition')->AttributeUpdate(
|
||||
AttributeID => $AttributeID,
|
||||
Name => 'DynamicField_' . $Param{Data}->{NewData}->{Name},
|
||||
UserID => 1,
|
||||
);
|
||||
|
||||
# check error
|
||||
if ( !$Success ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message =>
|
||||
"Could not update attribute name from '$Param{Data}->{OldData}->{Name}' to '$Param{Data}->{NewData}->{Name}'!",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
# dynamic field has been deleted
|
||||
elsif ( $Param{Event} eq 'DynamicFieldDelete' ) {
|
||||
|
||||
# get all condition attributes
|
||||
my $ConditionAttributes = $Kernel::OM->Get('Kernel::System::ITSMChange::ITSMCondition')->AttributeList(
|
||||
UserID => 1,
|
||||
);
|
||||
|
||||
# reverse the list to lookup attribute names
|
||||
my %Attribute2ID = reverse %{$ConditionAttributes};
|
||||
|
||||
# lookup attribute id
|
||||
my $AttributeID = $Attribute2ID{ 'DynamicField_' . $Param{Data}->{NewData}->{Name} } || '';
|
||||
|
||||
# do nothing if no attribute with this name exsists
|
||||
return if !$AttributeID;
|
||||
|
||||
# delete this attribute from expression table
|
||||
$Kernel::OM->Get('Kernel::System::DB')->Do(
|
||||
SQL => 'DELETE FROM condition_expression
|
||||
WHERE attribute_id = ?',
|
||||
Bind => [
|
||||
\$AttributeID,
|
||||
],
|
||||
);
|
||||
|
||||
# delete this attribute from action table
|
||||
$Kernel::OM->Get('Kernel::System::DB')->Do(
|
||||
SQL => 'DELETE FROM condition_action
|
||||
WHERE attribute_id = ?',
|
||||
Bind => [
|
||||
\$AttributeID,
|
||||
],
|
||||
);
|
||||
|
||||
# delete this attribute from attribute table
|
||||
$Kernel::OM->Get('Kernel::System::DB')->Do(
|
||||
SQL => 'DELETE FROM condition_attribute
|
||||
WHERE id = ?',
|
||||
Bind => [
|
||||
\$AttributeID,
|
||||
],
|
||||
);
|
||||
|
||||
# delete cache
|
||||
$Kernel::OM->Get('Kernel::System::Cache')->CleanUp(
|
||||
Type => 'ITSMChangeManagement',
|
||||
);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
1;
|
||||
275
Perl OTRS/Kernel/System/DynamicField/ObjectType/Article.pm
Normal file
275
Perl OTRS/Kernel/System/DynamicField/ObjectType/Article.pm
Normal file
@@ -0,0 +1,275 @@
|
||||
# --
|
||||
# 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::ObjectType::Article;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Scalar::Util;
|
||||
|
||||
use Kernel::System::VariableCheck qw(:all);
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::System::DB',
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::Ticket',
|
||||
'Kernel::System::Ticket::Article',
|
||||
'Kernel::System::Web::Request',
|
||||
);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Kernel::System::DynamicField::ObjectType::Article
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Article object handler for DynamicFields
|
||||
|
||||
=head1 PUBLIC INTERFACE
|
||||
|
||||
=head2 new()
|
||||
|
||||
usually, you want to create an instance of this
|
||||
by using Kernel::System::DynamicField::ObjectType::Article->new();
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
=head2 PostValueSet()
|
||||
|
||||
perform specific functions after the Value set for this object type.
|
||||
|
||||
my $Success = $DynamicFieldTicketHandlerObject->PostValueSet(
|
||||
DynamicFieldConfig => $DynamicFieldConfig, # complete config of the DynamicField
|
||||
ObjectID => $ObjectID, # ID of the current object that the field
|
||||
# must be linked to, e. g. TicketID
|
||||
Value => $Value, # Value to store, depends on backend type
|
||||
UserID => 123,
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub PostValueSet {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
for my $Needed (qw(DynamicFieldConfig ObjectID UserID)) {
|
||||
if ( !$Param{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# check DynamicFieldConfig (general)
|
||||
if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "The field configuration is invalid",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# check DynamicFieldConfig (internally)
|
||||
for my $Needed (qw(ID FieldType ObjectType)) {
|
||||
if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed in DynamicFieldConfig!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# This is a rare case where we don't have the TicketID of an article, even though the article API requires it.
|
||||
# Since this is not called often and we don't want to cache on per-article basis, get the ID directly from the
|
||||
# database and use it.
|
||||
#
|
||||
|
||||
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
||||
|
||||
my $TicketID;
|
||||
|
||||
return if !$DBObject->Prepare(
|
||||
SQL => '
|
||||
SELECT ticket_id
|
||||
FROM article
|
||||
WHERE id = ?',
|
||||
Bind => [ \$Param{ObjectID} ],
|
||||
Limit => 1,
|
||||
);
|
||||
|
||||
while ( my @Row = $DBObject->FetchrowArray() ) {
|
||||
$TicketID = $Row[0];
|
||||
}
|
||||
|
||||
if ( !$TicketID ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Could not determine TicketID of Article $Param{ArticleID}!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# update change time
|
||||
return if !$DBObject->Do(
|
||||
SQL => '
|
||||
UPDATE ticket
|
||||
SET change_time = current_timestamp, change_by = ?
|
||||
WHERE id = ?',
|
||||
Bind => [ \$Param{UserID}, \$TicketID ],
|
||||
);
|
||||
|
||||
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
|
||||
|
||||
$TicketObject->_TicketCacheClear( TicketID => $TicketID );
|
||||
|
||||
$TicketObject->EventHandler(
|
||||
Event => 'ArticleDynamicFieldUpdate',
|
||||
Data => {
|
||||
FieldName => $Param{DynamicFieldConfig}->{Name},
|
||||
Value => $Param{Value},
|
||||
OldValue => $Param{OldValue},
|
||||
TicketID => $TicketID,
|
||||
ArticleID => $Param{ObjectID},
|
||||
UserID => $Param{UserID},
|
||||
},
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head2 ObjectDataGet()
|
||||
|
||||
retrieves the data of the current object.
|
||||
|
||||
my %ObjectData = $DynamicFieldTicketHandlerObject->ObjectDataGet(
|
||||
DynamicFieldConfig => $DynamicFieldConfig, # complete config of the DynamicField
|
||||
UserID => 123,
|
||||
);
|
||||
|
||||
returns:
|
||||
|
||||
%ObjectData = (
|
||||
ObjectID => 123,
|
||||
Data => {
|
||||
ArticleID => 123,
|
||||
TicketID => 2,
|
||||
CommunicationChannelID => 1,
|
||||
SenderTypeID => 1,
|
||||
IsVisibleForCustomer => 0,
|
||||
# ...
|
||||
}
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub ObjectDataGet {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# Check needed stuff.
|
||||
for my $Needed (qw(DynamicFieldConfig UserID)) {
|
||||
if ( !$Param{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# Check DynamicFieldConfig (general).
|
||||
if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "The field configuration is invalid",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# Check DynamicFieldConfig (internally).
|
||||
for my $Needed (qw(ID FieldType ObjectType)) {
|
||||
if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed in DynamicFieldConfig!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
my $ParamObject = $Kernel::OM->Get('Kernel::System::Web::Request');
|
||||
|
||||
my $ArticleID = $ParamObject->GetParam(
|
||||
Param => 'ArticleID',
|
||||
);
|
||||
|
||||
return if !$ArticleID;
|
||||
|
||||
my $TicketID = $ParamObject->GetParam(
|
||||
Param => 'TicketID',
|
||||
);
|
||||
|
||||
my $ArticleObject = $Kernel::OM->Get('Kernel::System::Ticket::Article');
|
||||
|
||||
# In case TicketID is not in the web request, look for it using the article.
|
||||
if ( !$TicketID ) {
|
||||
$TicketID = $ArticleObject->TicketIDLookup(
|
||||
ArticleID => $ArticleID,
|
||||
);
|
||||
}
|
||||
|
||||
if ( !$TicketID ) {
|
||||
return (
|
||||
ObjectID => $ArticleID,
|
||||
Data => {},
|
||||
);
|
||||
}
|
||||
|
||||
my $ArticleBackendObject = $ArticleObject->BackendForArticle(
|
||||
ArticleID => $ArticleID,
|
||||
TicketID => $TicketID
|
||||
);
|
||||
|
||||
my %ArticleData = $ArticleBackendObject->ArticleGet(
|
||||
ArticleID => $ArticleID,
|
||||
DynamicFields => 1,
|
||||
TicketID => $TicketID,
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
return (
|
||||
ObjectID => $ArticleID,
|
||||
Data => \%ArticleData,
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 TERMS AND CONDITIONS
|
||||
|
||||
This software is part of the OTRS project (L<https://otrs.org/>).
|
||||
|
||||
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<https://www.gnu.org/licenses/gpl-3.0.txt>.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,208 @@
|
||||
# --
|
||||
# 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::ObjectType::CustomerCompany;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Kernel::System::VariableCheck qw(:all);
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::System::CustomerCompany',
|
||||
'Kernel::System::DynamicField',
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::Web::Request',
|
||||
);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Kernel::System::DynamicField::ObjectType::CustomerCompany
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
CustomerCompany object handler for DynamicFields
|
||||
|
||||
=head1 PUBLIC INTERFACE
|
||||
|
||||
=head2 new()
|
||||
|
||||
usually, you want to create an instance of this
|
||||
by using Kernel::System::DynamicField::ObjectType::CustomerCompany->new();
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
=head2 PostValueSet()
|
||||
|
||||
perform specific functions after the Value set for this object type.
|
||||
|
||||
my $Success = $DynamicFieldTicketHandlerObject->PostValueSet(
|
||||
DynamicFieldConfig => $DynamicFieldConfig, # complete config of the DynamicField
|
||||
ObjectID => $ObjectID, # ID of the current object that the field
|
||||
# must be linked to, e. g. TicketID
|
||||
Value => $Value, # Value to store, depends on backend type
|
||||
UserID => 123,
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub PostValueSet {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# Check needed stuff.
|
||||
for my $Needed (qw(DynamicFieldConfig ObjectID UserID)) {
|
||||
if ( !$Param{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# Check DynamicFieldConfig (general).
|
||||
if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "The field configuration is invalid",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# Check DynamicFieldConfig (internally).
|
||||
for my $Needed (qw(ID FieldType ObjectType)) {
|
||||
if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed in DynamicFieldConfig!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# Nothing to do here.
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head2 ObjectDataGet()
|
||||
|
||||
retrieves the data of the current object.
|
||||
|
||||
my %ObjectData = $DynamicFieldTicketHandlerObject->ObjectDataGet(
|
||||
DynamicFieldConfig => $DynamicFieldConfig, # complete config of the DynamicField
|
||||
UserID => 123,
|
||||
);
|
||||
|
||||
returns:
|
||||
|
||||
%ObjectData = (
|
||||
ObjectID => 123,
|
||||
Data => {
|
||||
CustomerCompanyName => 'Customer Inc.',
|
||||
CustomerID => 'example.com',
|
||||
CustomerCompanyStreet => '5201 Blue Lagoon Drive',
|
||||
CustomerCompanyZIP => '33126',
|
||||
# ...
|
||||
}
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub ObjectDataGet {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# Check needed stuff.
|
||||
for my $Needed (qw(DynamicFieldConfig UserID)) {
|
||||
if ( !$Param{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# Check DynamicFieldConfig (general).
|
||||
if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "The field configuration is invalid",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# Check DynamicFieldConfig (internally).
|
||||
for my $Needed (qw(ID FieldType ObjectType)) {
|
||||
if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed in DynamicFieldConfig!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
my $ParamObject = $Kernel::OM->Get('Kernel::System::Web::Request');
|
||||
my $CustomerID = $ParamObject->GetParam( Param => 'CustomerID' ) || $ParamObject->GetParam( Param => 'ID' ) || '';
|
||||
|
||||
my $ObjectID;
|
||||
|
||||
my $ObjectIDs = $Kernel::OM->Get('Kernel::System::DynamicField')->ObjectMappingGet(
|
||||
ObjectName => $CustomerID,
|
||||
ObjectType => $Param{DynamicFieldConfig}->{ObjectType},
|
||||
);
|
||||
|
||||
if ( IsHashRefWithData($ObjectIDs) && $ObjectIDs->{$CustomerID} ) {
|
||||
$ObjectID = $ObjectIDs->{$CustomerID};
|
||||
}
|
||||
else {
|
||||
$ObjectID = $Kernel::OM->Get('Kernel::System::DynamicField')->ObjectMappingCreate(
|
||||
ObjectName => $CustomerID,
|
||||
ObjectType => $Param{DynamicFieldConfig}->{ObjectType},
|
||||
);
|
||||
}
|
||||
|
||||
if ( !$ObjectID ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message =>
|
||||
"Unable to determine object id for object name $CustomerID and type $Param{DynamicFieldConfig}->{ObjectType}!"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
my %CustomerCompany = $Kernel::OM->Get('Kernel::System::CustomerCompany')->CustomerCompanyGet(
|
||||
CustomerID => $CustomerID,
|
||||
);
|
||||
|
||||
return (
|
||||
ObjectID => $ObjectID,
|
||||
Data => \%CustomerCompany,
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 TERMS AND CONDITIONS
|
||||
|
||||
This software is part of the OTRS project (L<https://otrs.org/>).
|
||||
|
||||
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<https://www.gnu.org/licenses/gpl-3.0.txt>.
|
||||
|
||||
=cut
|
||||
211
Perl OTRS/Kernel/System/DynamicField/ObjectType/CustomerUser.pm
Normal file
211
Perl OTRS/Kernel/System/DynamicField/ObjectType/CustomerUser.pm
Normal file
@@ -0,0 +1,211 @@
|
||||
# --
|
||||
# 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::ObjectType::CustomerUser;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Kernel::System::VariableCheck qw(:all);
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::System::CustomerUser',
|
||||
'Kernel::System::DynamicField',
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::Web::Request',
|
||||
);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Kernel::System::DynamicField::ObjectType::CustomerUser
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
CustomerUser object handler for DynamicFields
|
||||
|
||||
=head1 PUBLIC INTERFACE
|
||||
|
||||
=head2 new()
|
||||
|
||||
usually, you want to create an instance of this
|
||||
by using Kernel::System::DynamicField::ObjectType::CustomerUser->new();
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
=head2 PostValueSet()
|
||||
|
||||
perform specific functions after the Value set for this object type.
|
||||
|
||||
my $Success = $DynamicFieldTicketHandlerObject->PostValueSet(
|
||||
DynamicFieldConfig => $DynamicFieldConfig, # complete config of the DynamicField
|
||||
ObjectID => $ObjectID, # ID of the current object that the field
|
||||
# must be linked to, e. g. TicketID
|
||||
Value => $Value, # Value to store, depends on backend type
|
||||
UserID => 123,
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub PostValueSet {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# Check needed stuff.
|
||||
for my $Needed (qw(DynamicFieldConfig ObjectID UserID)) {
|
||||
if ( !$Param{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# Check DynamicFieldConfig (general).
|
||||
if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "The field configuration is invalid",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# Check DynamicFieldConfig (internally).
|
||||
for my $Needed (qw(ID FieldType ObjectType)) {
|
||||
if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed in DynamicFieldConfig!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# Nothing to do here
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head2 ObjectDataGet()
|
||||
|
||||
retrieves the data of the current object.
|
||||
|
||||
my %ObjectData = $DynamicFieldTicketHandlerObject->ObjectDataGet(
|
||||
DynamicFieldConfig => $DynamicFieldConfig, # complete config of the DynamicField
|
||||
UserID => 123,
|
||||
);
|
||||
|
||||
returns:
|
||||
|
||||
%ObjectData = (
|
||||
ObjectID => 123,
|
||||
Data => {
|
||||
UserLogin => 'jdoe',
|
||||
UserFirstname => 'John',
|
||||
UserLastname => 'Dome',
|
||||
UserEmail => 'j.doe@example.com',
|
||||
# ...
|
||||
}
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub ObjectDataGet {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# Check needed stuff.
|
||||
for my $Needed (qw(DynamicFieldConfig UserID)) {
|
||||
if ( !$Param{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# Check DynamicFieldConfig (general).
|
||||
if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "The field configuration is invalid",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# Check DynamicFieldConfig (internally).
|
||||
for my $Needed (qw(ID FieldType ObjectType)) {
|
||||
if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed in DynamicFieldConfig!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
my $UserID = $Kernel::OM->Get('Kernel::System::Web::Request')->GetParam( Param => 'ID' ) || '';
|
||||
|
||||
my $ObjectID;
|
||||
|
||||
my $DynamicFieldObject = $Kernel::OM->Get('Kernel::System::DynamicField');
|
||||
|
||||
my $ObjectIDs = $DynamicFieldObject->ObjectMappingGet(
|
||||
ObjectName => $UserID,
|
||||
ObjectType => $Param{DynamicFieldConfig}->{ObjectType},
|
||||
);
|
||||
|
||||
if ( IsHashRefWithData($ObjectIDs) && $ObjectIDs->{$UserID} ) {
|
||||
$ObjectID = $ObjectIDs->{$UserID};
|
||||
}
|
||||
else {
|
||||
$ObjectID = $DynamicFieldObject->ObjectMappingCreate(
|
||||
ObjectName => $UserID,
|
||||
ObjectType => $Param{DynamicFieldConfig}->{ObjectType},
|
||||
);
|
||||
}
|
||||
|
||||
if ( !$ObjectID ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message =>
|
||||
"Unable to determine object id for object name $UserID and type $Param{DynamicFieldConfig}->{ObjectType}!"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
my %UserData = $Kernel::OM->Get('Kernel::System::CustomerUser')->CustomerUserDataGet(
|
||||
User => $UserID,
|
||||
Valid => 1,
|
||||
);
|
||||
|
||||
return (
|
||||
ObjectID => $ObjectID,
|
||||
Data => \%UserData,
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 TERMS AND CONDITIONS
|
||||
|
||||
This software is part of the OTRS project (L<https://otrs.org/>).
|
||||
|
||||
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<https://www.gnu.org/licenses/gpl-3.0.txt>.
|
||||
|
||||
=cut
|
||||
228
Perl OTRS/Kernel/System/DynamicField/ObjectType/FAQ.pm
Normal file
228
Perl OTRS/Kernel/System/DynamicField/ObjectType/FAQ.pm
Normal file
@@ -0,0 +1,228 @@
|
||||
# --
|
||||
# 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::ObjectType::FAQ;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Scalar::Util;
|
||||
|
||||
use Kernel::System::VariableCheck qw(:all);
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::System::FAQ',
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::Web::Request',
|
||||
);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Kernel::System::DynamicField::ObjectType::FAQ
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
FAQ object handler for DynamicFields
|
||||
|
||||
=head1 PUBLIC INTERFACE
|
||||
|
||||
=head2 new()
|
||||
|
||||
usually, you want to create an instance of this
|
||||
by using Kernel::System::DynamicField::ObjectType::FAQ->new();
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
=head2 PostValueSet()
|
||||
|
||||
perform specific functions after the Value set for this object type.
|
||||
|
||||
my $Success = $DynamicFieldFAQHandlerObject->PostValueSet(
|
||||
DynamicFieldConfig => $DynamicFieldConfig, # complete config of the DynamicField
|
||||
ObjectID => $ObjectID, # ID of the current object that the field
|
||||
# must be linked to, e. g. FAQID
|
||||
Value => $Value, # Value to store, depends on backend type
|
||||
UserID => 123,
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub PostValueSet {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
for my $Needed (qw(DynamicFieldConfig ObjectID UserID)) {
|
||||
if ( !$Param{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed!"
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# check DynamicFieldConfig (general)
|
||||
if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "The field configuration is invalid",
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
# check DynamicFieldConfig (internally)
|
||||
for my $Needed (qw(ID FieldType ObjectType)) {
|
||||
if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed in DynamicFieldConfig!"
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
my $FAQObject = $Kernel::OM->Get('Kernel::System::FAQ');
|
||||
|
||||
# history insert
|
||||
$FAQObject->FAQHistoryAdd(
|
||||
Name => "DynamicField $Param{DynamicFieldConfig}->{Name} Updated",
|
||||
ItemID => $Param{ObjectID},
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
$FAQObject->_DeleteFromFAQCache( ItemID => $Param{ObjectID} );
|
||||
|
||||
# Trigger event.
|
||||
$FAQObject->EventHandler(
|
||||
Event => 'FAQDynamicFieldUpdate_' . $Param{DynamicFieldConfig}->{Name},
|
||||
Data => {
|
||||
FieldName => $Param{DynamicFieldConfig}->{Name},
|
||||
Value => $Param{Value},
|
||||
OldValue => $Param{OldValue},
|
||||
ItemID => $Param{ObjectID},
|
||||
UserID => $Param{UserID},
|
||||
},
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head2 ObjectDataGet()
|
||||
|
||||
retrieves the data of the current object.
|
||||
|
||||
my %ObjectData = $DynamicFieldFAQHandlerObject->ObjectDataGet(
|
||||
DynamicFieldConfig => $DynamicFieldConfig, # complete config of the DynamicField
|
||||
UserID => 123,
|
||||
);
|
||||
|
||||
returns:
|
||||
|
||||
%ObjectData = (
|
||||
ObjectID => 123,
|
||||
Data => {
|
||||
FAQID => 32,
|
||||
Number => 100032,
|
||||
CategoryID => '2',
|
||||
# ...
|
||||
}
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub ObjectDataGet {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
for my $Needed (qw(DynamicFieldConfig UserID)) {
|
||||
if ( !$Param{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# Check DynamicFieldConfig (general).
|
||||
if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "The field configuration is invalid",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# Check DynamicFieldConfig (internally).
|
||||
for my $Needed (qw(ID FieldType ObjectType)) {
|
||||
if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed in DynamicFieldConfig!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
my $ItemID = $Kernel::OM->Get('Kernel::System::Web::Request')->GetParam(
|
||||
Param => 'ItemID',
|
||||
);
|
||||
|
||||
return if !$ItemID;
|
||||
|
||||
my %FAQ = $Kernel::OM->Get('Kernel::System::FAQ')->FAQGet(
|
||||
ItemID => $ItemID,
|
||||
ItemFields => 1,
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
if ( !%FAQ ) {
|
||||
|
||||
return (
|
||||
ObjectID => $ItemID,
|
||||
Data => {}
|
||||
);
|
||||
}
|
||||
|
||||
my %Result = (
|
||||
ObjectID => $ItemID,
|
||||
);
|
||||
|
||||
ATTRIBUTE:
|
||||
for my $Attribute ( sort keys %FAQ ) {
|
||||
|
||||
$Result{Data}->{$Attribute} = $FAQ{$Attribute};
|
||||
}
|
||||
|
||||
return %Result;
|
||||
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 TERMS AND CONDITIONS
|
||||
|
||||
This software is part of the OTRS project (L<https://otrs.org/>).
|
||||
|
||||
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<https://www.gnu.org/licenses/gpl-3.0.txt>.
|
||||
|
||||
=cut
|
||||
187
Perl OTRS/Kernel/System/DynamicField/ObjectType/ITSMChange.pm
Normal file
187
Perl OTRS/Kernel/System/DynamicField/ObjectType/ITSMChange.pm
Normal file
@@ -0,0 +1,187 @@
|
||||
# --
|
||||
# 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::ObjectType::ITSMChange;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Scalar::Util;
|
||||
use Kernel::System::VariableCheck qw(:all);
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::ITSMChange',
|
||||
'Kernel::System::Web::Request',
|
||||
);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Kernel::System::DynamicField::ObjectType::ITSMChange
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
ITSMChange object handler for DynamicFields
|
||||
|
||||
=head1 PUBLIC INTERFACE
|
||||
|
||||
=head2 new()
|
||||
|
||||
Usually, you want to create an instance of this
|
||||
by using Kernel::System::DynamicField::ObjectType::ITSMChange->new();
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
=head2 PostValueSet()
|
||||
|
||||
Perform specific functions after the Value set for this object type.
|
||||
|
||||
my $Success = $DynamicFieldITSMChangeHandlerObject->PostValueSet(
|
||||
DynamicFieldConfig => $DynamicFieldConfig, # complete config of the DynamicField
|
||||
ObjectID => $ObjectID, # ID of the current object that the field
|
||||
# must be linked to, e. g. ITSMChangeID
|
||||
Value => $Value, # Value to store, depends on backend type
|
||||
UserID => 123,
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub PostValueSet {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
for my $Needed (qw(DynamicFieldConfig ObjectID UserID)) {
|
||||
if ( !$Param{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# check DynamicFieldConfig (general)
|
||||
if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "The field configuration is invalid",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# check DynamicFieldConfig (internally)
|
||||
for my $Needed (qw(ID FieldType ObjectType)) {
|
||||
if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed in DynamicFieldConfig!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# nothing to do
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head2 ObjectDataGet()
|
||||
|
||||
retrieves the data of the current object.
|
||||
|
||||
my %ObjectData = $DynamicFieldITSMChangeHandlerObject->ObjectDataGet(
|
||||
DynamicFieldConfig => $DynamicFieldConfig, # complete config of the DynamicField
|
||||
UserID => 123,
|
||||
);
|
||||
|
||||
returns:
|
||||
|
||||
%ObjectData = (
|
||||
ObjectID => 123,
|
||||
Data => {
|
||||
ChangeNumber => '20101027000001',
|
||||
Title => 'some title',
|
||||
ChangeID => 123,
|
||||
# ...
|
||||
}
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub ObjectDataGet {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# Check needed stuff.
|
||||
for my $Needed (qw(DynamicFieldConfig UserID)) {
|
||||
if ( !$Param{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# Check DynamicFieldConfig (general).
|
||||
if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "The field configuration is invalid",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# Check DynamicFieldConfig (internally).
|
||||
for my $Needed (qw(ID FieldType ObjectType)) {
|
||||
if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed in DynamicFieldConfig!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
my $ChangeID = $Kernel::OM->Get('Kernel::System::Web::Request')->GetParam(
|
||||
Param => 'ChangeID',
|
||||
);
|
||||
|
||||
return if !$ChangeID;
|
||||
|
||||
my %ChangeData = $Kernel::OM->Get('Kernel::System::ITSMChange')->ChangeGet(
|
||||
ChangeID => $ChangeID,
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
return (
|
||||
ObjectID => $ChangeID,
|
||||
Data => \%ChangeData,
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 TERMS AND CONDITIONS
|
||||
|
||||
This software is part of the OTRS project (L<https://otrs.org/>).
|
||||
|
||||
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<https://www.gnu.org/licenses/gpl-3.0.txt>.
|
||||
|
||||
=cut
|
||||
187
Perl OTRS/Kernel/System/DynamicField/ObjectType/ITSMWorkOrder.pm
Normal file
187
Perl OTRS/Kernel/System/DynamicField/ObjectType/ITSMWorkOrder.pm
Normal file
@@ -0,0 +1,187 @@
|
||||
# --
|
||||
# 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::ObjectType::ITSMWorkOrder;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Scalar::Util;
|
||||
use Kernel::System::VariableCheck qw(:all);
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::ITSMChange::ITSMWorkOrder',
|
||||
'Kernel::System::Web::Request',
|
||||
);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Kernel::System::DynamicField::ObjectType::ITSMWorkOrder
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
ITSMWorkOrder object handler for DynamicFields
|
||||
|
||||
=head1 PUBLIC INTERFACE
|
||||
|
||||
=head2 new()
|
||||
|
||||
Usually, you want to create an instance of this
|
||||
by using Kernel::System::DynamicField::ObjectType::ITSMWorkOrder->new();
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
=head2 PostValueSet()
|
||||
|
||||
Perform specific functions after the Value set for this object type.
|
||||
|
||||
my $Success = $DynamicFieldITSMWorkOrderHandlerObject->PostValueSet(
|
||||
DynamicFieldConfig => $DynamicFieldConfig, # complete config of the DynamicField
|
||||
ObjectID => $ObjectID, # ID of the current object that the field
|
||||
# must be linked to, e. g. ITSMWorkOrderID
|
||||
Value => $Value, # Value to store, depends on backend type
|
||||
UserID => 123,
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub PostValueSet {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
for my $Needed (qw(DynamicFieldConfig ObjectID UserID)) {
|
||||
if ( !$Param{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# check DynamicFieldConfig (general)
|
||||
if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "The field configuration is invalid",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# check DynamicFieldConfig (internally)
|
||||
for my $Needed (qw(ID FieldType ObjectType)) {
|
||||
if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed in DynamicFieldConfig!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# nothing to do
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head2 ObjectDataGet()
|
||||
|
||||
retrieves the data of the current object.
|
||||
|
||||
my %ObjectData = $DynamicFieldITSMWorkOrderHandlerObject->ObjectDataGet(
|
||||
DynamicFieldConfig => $DynamicFieldConfig, # complete config of the DynamicField
|
||||
UserID => 123,
|
||||
);
|
||||
|
||||
returns:
|
||||
|
||||
%ObjectData = (
|
||||
ObjectID => 123,
|
||||
Data => {
|
||||
WorkOrderNumber => '20101027000001',
|
||||
Title => 'some title',
|
||||
WorkOrderID => 123,
|
||||
# ...
|
||||
}
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub ObjectDataGet {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# Check needed stuff.
|
||||
for my $Needed (qw(DynamicFieldConfig UserID)) {
|
||||
if ( !$Param{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# Check DynamicFieldConfig (general).
|
||||
if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "The field configuration is invalid",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# Check DynamicFieldConfig (internally).
|
||||
for my $Needed (qw(ID FieldType ObjectType)) {
|
||||
if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed in DynamicFieldConfig!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
my $WorkOrderID = $Kernel::OM->Get('Kernel::System::Web::Request')->GetParam(
|
||||
Param => 'WorkOrderID',
|
||||
);
|
||||
|
||||
return if !$WorkOrderID;
|
||||
|
||||
my %WorkOrderData = $Kernel::OM->Get('Kernel::System::ITSMChange::ITSMWorkOrder')->WorkOrderGet(
|
||||
WorkOrderID => $WorkOrderID,
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
return (
|
||||
ObjectID => $WorkOrderID,
|
||||
Data => \%WorkOrderData,
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 TERMS AND CONDITIONS
|
||||
|
||||
This software is part of the OTRS project (L<https://otrs.org/>).
|
||||
|
||||
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<https://www.gnu.org/licenses/gpl-3.0.txt>.
|
||||
|
||||
=cut
|
||||
357
Perl OTRS/Kernel/System/DynamicField/ObjectType/Ticket.pm
Normal file
357
Perl OTRS/Kernel/System/DynamicField/ObjectType/Ticket.pm
Normal file
@@ -0,0 +1,357 @@
|
||||
# --
|
||||
# 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::ObjectType::Ticket;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Scalar::Util;
|
||||
|
||||
use Kernel::System::VariableCheck qw(:all);
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::System::DB',
|
||||
'Kernel::System::DynamicField::Backend',
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::Ticket',
|
||||
'Kernel::System::Web::Request',
|
||||
);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Kernel::System::DynamicField::ObjectType::Ticket
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Ticket object handler for DynamicFields
|
||||
|
||||
=head1 PUBLIC INTERFACE
|
||||
|
||||
=head2 new()
|
||||
|
||||
usually, you want to create an instance of this
|
||||
by using Kernel::System::DynamicField::ObjectType::Ticket->new();
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
=head2 PostValueSet()
|
||||
|
||||
perform specific functions after the Value set for this object type.
|
||||
|
||||
my $Success = $DynamicFieldTicketHandlerObject->PostValueSet(
|
||||
DynamicFieldConfig => $DynamicFieldConfig, # complete config of the DynamicField
|
||||
ObjectID => $ObjectID, # ID of the current object that the field
|
||||
# must be linked to, e. g. TicketID
|
||||
Value => $Value, # Value to store, depends on backend type
|
||||
UserID => 123,
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub PostValueSet {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
for my $Needed (qw(DynamicFieldConfig ObjectID UserID)) {
|
||||
if ( !$Param{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# check DynamicFieldConfig (general)
|
||||
if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "The field configuration is invalid",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# check DynamicFieldConfig (internally)
|
||||
for my $Needed (qw(ID FieldType ObjectType)) {
|
||||
if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed in DynamicFieldConfig!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# get database object
|
||||
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
||||
|
||||
# update change time
|
||||
return if !$DBObject->Do(
|
||||
SQL => 'UPDATE ticket SET change_time = current_timestamp, '
|
||||
. ' change_by = ? WHERE id = ?',
|
||||
Bind => [ \$Param{UserID}, \$Param{ObjectID} ],
|
||||
);
|
||||
|
||||
# get ticket object
|
||||
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
|
||||
|
||||
my %Ticket = $TicketObject->TicketGet(
|
||||
TicketID => $Param{ObjectID},
|
||||
DynamicFields => 0,
|
||||
);
|
||||
|
||||
my $HistoryValue = defined $Param{Value} ? $Param{Value} : '';
|
||||
my $HistoryOldValue = defined $Param{OldValue} ? $Param{OldValue} : '';
|
||||
|
||||
# get dynamic field backend object
|
||||
my $DynamicFieldBackendObject = $Kernel::OM->Get('Kernel::System::DynamicField::Backend');
|
||||
|
||||
# get value for storing
|
||||
my $ValueStrg = $DynamicFieldBackendObject->ReadableValueRender(
|
||||
DynamicFieldConfig => $Param{DynamicFieldConfig},
|
||||
Value => $HistoryValue,
|
||||
);
|
||||
$HistoryValue = $ValueStrg->{Value};
|
||||
|
||||
my $OldValueStrg = $DynamicFieldBackendObject->ReadableValueRender(
|
||||
DynamicFieldConfig => $Param{DynamicFieldConfig},
|
||||
Value => $HistoryOldValue,
|
||||
);
|
||||
$HistoryOldValue = $OldValueStrg->{Value};
|
||||
|
||||
my $FieldName;
|
||||
if ( !defined $Param{DynamicFieldConfig}->{Name} ) {
|
||||
$FieldName = '';
|
||||
}
|
||||
else {
|
||||
$FieldName = $Param{DynamicFieldConfig}->{Name};
|
||||
}
|
||||
|
||||
my $FieldNameLength = length $FieldName || 0;
|
||||
my $HistoryValueLength = length $HistoryValue || 0;
|
||||
my $HistoryOldValueLength = length $HistoryOldValue || 0;
|
||||
|
||||
# Name in ticket_history is like this form "\%\%FieldName\%\%$FieldName\%\%Value\%\%$HistoryValue\%\%OldValue\%\%$HistoryOldValue" up to 200 chars
|
||||
# \%\%FieldName\%\% is 13 chars
|
||||
# \%\%Value\%\% is 9 chars
|
||||
# \%\%OldValue\%\%$HistoryOldValue is 12
|
||||
# we have for info part of ticket history data ($FieldName+$HistoryValue+$OldValue) up to 166 chars
|
||||
# in this code is made substring. The same number of characters is provided for both of part in Name ($FieldName and $HistoryValue and $OldVAlue) up to 55 chars
|
||||
# if $FieldName and $HistoryValue and $OldVAlue is cut then info is up to 50 chars plus [...] (5 chars)
|
||||
# First it is made $HistoryOldValue, then it is made $FieldName, and then $HistoryValue
|
||||
# Length $HistoryValue can be longer then 55 chars, also is for $OldValue.
|
||||
|
||||
my $NoCharacters = 166;
|
||||
|
||||
if ( ( $FieldNameLength + $HistoryValueLength + $HistoryOldValueLength ) > $NoCharacters ) {
|
||||
|
||||
# OldValue is maybe less important
|
||||
# At first it is made HistoryOldValue
|
||||
# and now it is possible that for HistoryValue would FieldName be more than 55 chars
|
||||
if ( length($HistoryOldValue) > 55 ) {
|
||||
$HistoryOldValue = substr( $HistoryOldValue, 0, 50 );
|
||||
$HistoryOldValue .= '[...]';
|
||||
}
|
||||
|
||||
# limit FieldName to 55 chars if is necessary
|
||||
my $FieldNameLength = int( ( $NoCharacters - length($HistoryOldValue) ) / 2 );
|
||||
my $ValueLength = $FieldNameLength;
|
||||
if ( length($FieldName) > $FieldNameLength ) {
|
||||
|
||||
# HistoryValue will be at least 55 chars or more, if is FieldName or HistoryOldValue less than 55 chars
|
||||
if ( length($HistoryValue) > $ValueLength ) {
|
||||
$FieldNameLength = $FieldNameLength - 5;
|
||||
$FieldName = substr( $FieldName, 0, $FieldNameLength );
|
||||
$FieldName .= '[...]';
|
||||
$ValueLength = $ValueLength - 5;
|
||||
$HistoryValue = substr( $HistoryValue, 0, $ValueLength );
|
||||
$HistoryValue .= '[...]';
|
||||
}
|
||||
else {
|
||||
$FieldNameLength = $NoCharacters - length($HistoryOldValue) - length($HistoryValue) - 5;
|
||||
$FieldName = substr( $FieldName, 0, $FieldNameLength );
|
||||
$FieldName .= '[...]';
|
||||
}
|
||||
}
|
||||
else {
|
||||
$ValueLength = $NoCharacters - length($HistoryOldValue) - length($FieldName) - 5;
|
||||
if ( length($HistoryValue) > $ValueLength ) {
|
||||
$HistoryValue = substr( $HistoryValue, 0, $ValueLength );
|
||||
$HistoryValue .= '[...]';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$HistoryValue //= '';
|
||||
$HistoryOldValue //= '';
|
||||
|
||||
# Add history entry.
|
||||
$TicketObject->HistoryAdd(
|
||||
TicketID => $Param{ObjectID},
|
||||
QueueID => $Ticket{QueueID},
|
||||
HistoryType => 'TicketDynamicFieldUpdate',
|
||||
|
||||
# This insert is not optimal at all (not human readable), but will be kept due to backwards compatibility. The
|
||||
# value will be converted for use in a more speaking form directly in AgentTicketHistory.pm before display.
|
||||
Name =>
|
||||
"\%\%FieldName\%\%$FieldName"
|
||||
. "\%\%Value\%\%$HistoryValue"
|
||||
. "\%\%OldValue\%\%$HistoryOldValue",
|
||||
CreateUserID => $Param{UserID},
|
||||
);
|
||||
|
||||
# clear ticket cache
|
||||
$TicketObject->_TicketCacheClear( TicketID => $Param{ObjectID} );
|
||||
|
||||
# Trigger event.
|
||||
$TicketObject->EventHandler(
|
||||
Event => 'TicketDynamicFieldUpdate_' . $Param{DynamicFieldConfig}->{Name},
|
||||
Data => {
|
||||
FieldName => $Param{DynamicFieldConfig}->{Name},
|
||||
Value => $Param{Value},
|
||||
OldValue => $Param{OldValue},
|
||||
TicketID => $Param{ObjectID},
|
||||
UserID => $Param{UserID},
|
||||
},
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head2 ObjectDataGet()
|
||||
|
||||
retrieves the data of the current object.
|
||||
|
||||
my %ObjectData = $DynamicFieldTicketHandlerObject->ObjectDataGet(
|
||||
DynamicFieldConfig => $DynamicFieldConfig, # complete config of the DynamicField
|
||||
UserID => 123,
|
||||
);
|
||||
|
||||
returns:
|
||||
|
||||
%ObjectData = (
|
||||
ObjectID => 123,
|
||||
Data => {
|
||||
TicketNumber => '20101027000001',
|
||||
Title => 'some title',
|
||||
TicketID => 123,
|
||||
# ...
|
||||
}
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub ObjectDataGet {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# Check needed stuff.
|
||||
for my $Needed (qw(DynamicFieldConfig UserID)) {
|
||||
if ( !$Param{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# Check DynamicFieldConfig (general).
|
||||
if ( !IsHashRefWithData( $Param{DynamicFieldConfig} ) ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "The field configuration is invalid",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# Check DynamicFieldConfig (internally).
|
||||
for my $Needed (qw(ID FieldType ObjectType)) {
|
||||
if ( !$Param{DynamicFieldConfig}->{$Needed} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $Needed in DynamicFieldConfig!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
my $TicketID = $Kernel::OM->Get('Kernel::System::Web::Request')->GetParam(
|
||||
Param => 'TicketID',
|
||||
);
|
||||
|
||||
return if !$TicketID;
|
||||
|
||||
my %TicketData = $Kernel::OM->Get('Kernel::System::Ticket')->TicketGet(
|
||||
TicketID => $TicketID,
|
||||
DynamicFields => 1,
|
||||
Extended => 1,
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
if ( !%TicketData ) {
|
||||
|
||||
return (
|
||||
ObjectID => $TicketID,
|
||||
Data => {}
|
||||
);
|
||||
}
|
||||
|
||||
my %SkipAttributes = (
|
||||
Age => 1,
|
||||
EscalationDestinationIn => 1,
|
||||
EscalationDestinationTime => 1,
|
||||
EscalationSolutionTime => 1,
|
||||
EscalationTime => 1,
|
||||
EscalationTimeWorkingTime => 1,
|
||||
RealTillTimeNotUsed => 1,
|
||||
SolutionTime => 1,
|
||||
SolutionTimeDestinationTime => 1,
|
||||
SolutionTimeEscalation => 1,
|
||||
SolutionTimeWorkingTime => 1,
|
||||
UnlockTimeout => 1,
|
||||
UntilTime => 1,
|
||||
);
|
||||
|
||||
my %Result = (
|
||||
ObjectID => $TicketID,
|
||||
);
|
||||
|
||||
ATTRIBUTE:
|
||||
for my $Attribute ( sort keys %TicketData ) {
|
||||
|
||||
next ATTRIBUTE if $SkipAttributes{$Attribute};
|
||||
|
||||
$Result{Data}->{$Attribute} = $TicketData{$Attribute};
|
||||
}
|
||||
|
||||
return %Result;
|
||||
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 TERMS AND CONDITIONS
|
||||
|
||||
This software is part of the OTRS project (L<https://otrs.org/>).
|
||||
|
||||
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<https://www.gnu.org/licenses/gpl-3.0.txt>.
|
||||
|
||||
=cut
|
||||
Reference in New Issue
Block a user