Skip to content

Commit

Permalink
Merge pull request #2328 from RotherOSS/issue-#2327-json_response
Browse files Browse the repository at this point in the history
Issue #2327 json response
  • Loading branch information
bschmalhofer authored Jun 3, 2023
2 parents 9fbc778 + fe577b1 commit 9bdc326
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 99 deletions.
151 changes: 67 additions & 84 deletions Kernel/Modules/AgentContactWDSearch.pm
Original file line number Diff line number Diff line change
Expand Up @@ -27,68 +27,63 @@ sub new {
my ( $Type, %Param ) = @_;

# allocate new hash for object
my $Self = {%Param};
bless( $Self, $Type );

return $Self;
return bless {%Param}, $Type;
}

sub Run {
my ( $Self, %Param ) = @_;

my $JSON = '';

# search customers
if ( !$Self->{Subaction} ) {

# get needed params
my $ParamObject = $Kernel::OM->Get('Kernel::System::Web::Request');
my $Search = $ParamObject->GetParam( Param => 'Term' ) || '';
my $MaxResults = int( $ParamObject->GetParam( Param => 'MaxResults' ) || 20 );
my $FieldName = $ParamObject->GetParam( Param => 'Field' );

my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
if (
!$FieldName
||
(
$FieldName !~ m{ \A Autocomplete_DynamicField_ (.*) \z }xms
&& $FieldName !~ m{ \A Search_DynamicField_ (.*) \z }xms
)
)
{
return $Self->_ReturnJSON(
Content => $LayoutObject->JSONEncode(
Data => {
Success => 0,
Messsage => 'Need Field!',
}
),
);
}
else {
$FieldName = $1; # effectively remove prefix Autocomplete_DynamicField_ or Search_DynamicField_
}
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');

# get dynamic field
my $DynamicField = $Kernel::OM->Get('Kernel::System::DynamicField')->DynamicFieldGet(
Name => $FieldName,
# Return empty list when Subaction was passed as subactions are not supported here.
return $LayoutObject->JSONReply( Data => [] ) if $Self->{Subaction};

# Get FieldName from $ParamObject, bail out when not found
my $ParamObject = $Kernel::OM->Get('Kernel::System::Web::Request');
my $FieldName = $ParamObject->GetParam( Param => 'Field' );
if (
!$FieldName
||
(
$FieldName !~ m{ \A Autocomplete_DynamicField_ (.*) \z }xms
&& $FieldName !~ m{ \A Search_DynamicField_ (.*) \z }xms
)
)
{
return $LayoutObject->JSONReply(
Data => {
Success => 0,
Messsage => 'Need Field!',
}
);
if (
!IsHashRefWithData($DynamicField)
|| $DynamicField->{FieldType} ne 'ContactWD'
|| $DynamicField->{ValidID} ne 1
)
{
return $Self->_ReturnJSON(
Content => $LayoutObject->JSONEncode(
Data => {
Success => 0,
Messsage => 'Error reading dynamic field!',
}
),
);
}
}
else {
$FieldName = $1; # effectively remove prefix Autocomplete_DynamicField_ or Search_DynamicField_
}

# Get config for the dynamic field and check the sanity
my $DynamicField = $Kernel::OM->Get('Kernel::System::DynamicField')->DynamicFieldGet(
Name => $FieldName,
);
if (
!IsHashRefWithData($DynamicField)
|| $DynamicField->{FieldType} ne 'ContactWD'
|| $DynamicField->{ValidID} ne 1
)
{
return $LayoutObject->JSONReply(
Data => {
Success => 0,
Messsage => 'Error reading dynamic field!',
}
);
}

# search contacts, rthe results will be returned as JSON
my @Results;
{
my $Search = $ParamObject->GetParam( Param => 'Term' ) || '';
my $RemainingResultCount = int( $ParamObject->GetParam( Param => 'MaxResults' ) || 20 );

# make search safe and use '*' as wildcard
$Search =~ s{ \A \s+ }{}xms;
Expand All @@ -103,55 +98,43 @@ sub Run {
$Search =~ s{ Z \z }{}xms;

# get possible contacts
my @Data;
my $MaxResultCount = $MaxResults;
my $PossibleContacts = $DynamicField->{Config}->{ContactsWithData};
my $SearchableFields = $DynamicField->{Config}->{SearchableFieldsComputed};
CONTACT:
for my $Contact ( sort { lc($a) cmp lc($b) } keys %{$PossibleContacts} ) {

# check whether the contact matches the search term
my %ContactData = %{ $PossibleContacts->{$Contact} };
my $SearchMatch;
FIELD:
for my $Field ( @{$SearchableFields} ) {
next FIELD if $ContactData{$Field} !~ m{ $Search }xmsi;

$SearchMatch = 1;

last FIELD;
}
next CONTACT if !$SearchMatch;

next CONTACT if !$ContactData{ValidID};
next CONTACT if $ContactData{ValidID} ne 1;
push @Data, {
next CONTACT unless $SearchMatch;

# only valid contacts are returned
next CONTACT unless $ContactData{ValidID};
next CONTACT unless $ContactData{ValidID} eq 1;

push @Results, {
Key => $Contact,
Value => $ContactData{Name},
};
$MaxResultCount--;
last CONTACT if $MaxResultCount <= 0;
}
$RemainingResultCount--;

# build JSON output
$JSON = $LayoutObject->JSONEncode(
Data => \@Data,
);
# only a limited number of contacts are returned
last CONTACT if $RemainingResultCount <= 0;
}
}

return $Self->_ReturnJSON(
Content => $JSON,
return $LayoutObject->JSONReply(
Data => \@Results,
);
}

sub _ReturnJSON {
my ( $Self, %Param ) = @_;

# send JSON response
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
return $LayoutObject->Attachment(
ContentType => 'application/json',
Content => $Param{Content} || '',
Type => 'inline',
NoCache => 1,
);

}

1;
88 changes: 73 additions & 15 deletions Kernel/Output/HTML/Layout.pm
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,8 @@ sub SetEnv {
Priority => 'error',
Message => "Need $_!"
);
$Self->FatalError();

$Self->FatalError;
}
}
$Self->{EnvNewRef}->{ $Param{Key} } = $Param{Value};
Expand Down Expand Up @@ -521,20 +522,36 @@ sub Block {

=head2 JSONEncode()
Encode perl data structure to JSON string
Serialize a Perl data structure as JSON.
my %Hash = (
Key1 => 'Something',
Key2 => [ "Foo", "Bar" ],
);
my $JSON = $LayoutObject->JSONEncode(
Data => $Data,
NoQuotes => 0|1, # optional: no double quotes at the start and the end of JSON string
Data => \%Hash,
NoQuotes => 0, # optional: 0|1 no double quotes at the start and the end of JSON string, default is 0
);
Returns:
$JSON = <<'END_JSON';
{
"Key1" : "Something",
"Key2" : [
"Foo",
"Bar"
],
}
END_JSON
=cut

sub JSONEncode {
my ( $Self, %Param ) = @_;

# check for needed data
return if !defined $Param{Data};
return unless defined $Param{Data};

# get JSON encoded data
my $JSON = $Kernel::OM->Get('Kernel::System::JSON')->Encode(
Expand Down Expand Up @@ -2456,14 +2473,16 @@ sub BuildSelection {
Priority => 'error',
Message => 'Need Depend Param Ajax option!',
);
$Self->FatalError();

$Self->FatalError;
}
if ( !$Param{Ajax}->{Update} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => 'Need Update Param Ajax option()!',
);
$Self->FatalError();

$Self->FatalError;
}
my $Selector = $Param{ID} || $Param{Name};
$Param{OnChange} = "Core.AJAX.FormUpdate(\$('#"
Expand Down Expand Up @@ -2515,7 +2534,8 @@ sub BuildSelection {
Priority => 'error',
Message => 'Each Filter must provide Name and Values!',
);
$Self->FatalError();

$Self->FatalError;
}
$Index++;
}
Expand Down Expand Up @@ -2603,7 +2623,8 @@ sub Permission {
Priority => 'error',
Message => "Got no $Needed!",
);
$Self->FatalError();

$Self->FatalError;
}
}

Expand Down Expand Up @@ -2667,7 +2688,7 @@ returns browser output to display/download a attachment.
# scripts, flash etc.
);
Or for AJAX html snippets:
Or for AJAX HTML snippets:
$HTML = $LayoutObject->Attachment(
Type => 'inline', # optional, default: attachment, possible: inline|attachment
Expand All @@ -2692,7 +2713,8 @@ sub Attachment {
Priority => 'error',
Message => "Got no $_!",
);
$Self->FatalError();

$Self->FatalError;
}
}

Expand Down Expand Up @@ -2773,6 +2795,40 @@ sub Attachment {
return $Param{Content};
}

=head2 JSONReply()
Give back a data structure as a JSON response.
A bit like the method C<Attachments>.
As a side effect headers of the HTTP response are set in the object C<Kernel::System::Web::Response>.
=cut

sub JSONReply {
my ( $Self, %Param ) = @_;

# check needed params
for my $Needed (qw(Data)) {
if ( !defined $Param{$Needed} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Got no $Needed!",
);

$Self->FatalError;
}
}
my $Content = $Self->JSONEncode(
Data => \$Param{Data},
);

return $Self->Attachment(
ContentType => 'application/json',
Content => $Content || '',
Type => 'inline',
NoCache => 1,
);
}

=head2 PageNavBar()
generates a page navigation bar
Expand Down Expand Up @@ -4447,7 +4503,7 @@ sub CustomerFatalError {
my ( $Self, %Param ) = @_;

# Prevent endless recursion in case of problems with Template engine.
return if ( $Self->{InFatalError}++ );
return if $Self->{InFatalError}++;

if ( $Param{Message} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Expand Down Expand Up @@ -4664,7 +4720,7 @@ sub CustomerNavigationBar {

# load module
if ( !$MainObject->Require( $Jobs{$Job}->{Module} ) ) {
$Self->FatalError();
$Self->FatalError;
}
my $Object = $Jobs{$Job}->{Module}->new(
%{$Self},
Expand Down Expand Up @@ -6239,7 +6295,8 @@ sub SetRichTextParameters {
Priority => 'error',
Message => "Need HashRef in Param Data! Got: '" . ref( $Param{Data} ) . "'!",
);
$Self->FatalError();

$Self->FatalError;
}

# get needed objects
Expand Down Expand Up @@ -6377,7 +6434,8 @@ sub CustomerSetRichTextParameters {
Priority => 'error',
Message => "Need HashRef in Param Data! Got: '" . ref( $Param{Data} ) . "'!",
);
$Self->FatalError();

$Self->FatalError;
}

# get needed objects
Expand Down

0 comments on commit 9bdc326

Please sign in to comment.