425 lines
12 KiB
Perl
425 lines
12 KiB
Perl
# --
|
|
# 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::Modules::PublicFAQZoom;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use MIME::Base64 qw();
|
|
use Kernel::Language qw(Translatable);
|
|
use Kernel::System::VariableCheck qw(:all);
|
|
|
|
our $ObjectManagerDisabled = 1;
|
|
|
|
sub new {
|
|
my ( $Type, %Param ) = @_;
|
|
|
|
# allocate new hash for object
|
|
my $Self = {%Param};
|
|
bless( $Self, $Type );
|
|
|
|
# set UserID to root because in public interface there is no user
|
|
$Self->{UserID} = 1;
|
|
|
|
return $Self;
|
|
}
|
|
|
|
sub Run {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
my $ParamObject = $Kernel::OM->Get('Kernel::System::Web::Request');
|
|
|
|
# get params
|
|
my %GetParam;
|
|
$GetParam{ItemID} = $ParamObject->GetParam( Param => 'ItemID' );
|
|
|
|
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
|
|
|
|
if ( !$GetParam{ItemID} ) {
|
|
return $LayoutObject->CustomerFatalError(
|
|
Message => Translatable('Need ItemID!'),
|
|
);
|
|
}
|
|
|
|
# get back link
|
|
$GetParam{ZoomBackLink} = $ParamObject->GetParam( Param => 'ZoomBackLink' ) || '';
|
|
if ( $GetParam{ZoomBackLink} ) {
|
|
$GetParam{ZoomBackLink} = MIME::Base64::decode_base64( $GetParam{ZoomBackLink} );
|
|
}
|
|
|
|
my $FAQObject = $Kernel::OM->Get('Kernel::System::FAQ');
|
|
|
|
my %FAQData = $FAQObject->FAQGet(
|
|
ItemID => $GetParam{ItemID},
|
|
ItemFields => 1,
|
|
UserID => $Self->{UserID},
|
|
);
|
|
if ( !%FAQData ) {
|
|
return $LayoutObject->CustomerFatalError();
|
|
}
|
|
|
|
# get the valid ids
|
|
my @ValidIDs = $Kernel::OM->Get('Kernel::System::Valid')->ValidIDsGet();
|
|
my %ValidIDLookup = map { $_ => 1 } @ValidIDs;
|
|
|
|
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
|
|
|
|
# get interface state list
|
|
my $InterfaceStates = $FAQObject->StateTypeList(
|
|
Types => $ConfigObject->Get('FAQ::Public::StateTypes'),
|
|
UserID => $Self->{UserID},
|
|
);
|
|
|
|
# permission check
|
|
if (
|
|
!$FAQData{Approved}
|
|
|| !$ValidIDLookup{ $FAQData{ValidID} }
|
|
|| !$InterfaceStates->{ $FAQData{StateTypeID} }
|
|
)
|
|
{
|
|
return $LayoutObject->CustomerNoPermission(
|
|
WithHeader => 'yes',
|
|
);
|
|
}
|
|
|
|
# ---------------------------------------------------------- #
|
|
# HTMLView Sub-action
|
|
# ---------------------------------------------------------- #
|
|
if ( $Self->{Subaction} eq 'HTMLView' ) {
|
|
|
|
# get params
|
|
my $Field = $ParamObject->GetParam( Param => "Field" );
|
|
|
|
for my $Needed (qw( ItemID Field )) {
|
|
if ( !$Needed ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Needed Param: $Needed!",
|
|
);
|
|
return;
|
|
}
|
|
}
|
|
|
|
# get the Field content
|
|
my $FieldContent = $FAQObject->ItemFieldGet(
|
|
ItemID => $GetParam{ItemID},
|
|
Field => $Field,
|
|
UserID => $Self->{UserID},
|
|
);
|
|
|
|
# rewrite handle and action
|
|
$FieldContent
|
|
=~ s{ index[.]pl [?] Action=AgentFAQZoom }{public.pl?Action=PublicFAQZoom}gxms;
|
|
|
|
# take care of old style before FAQ 2.0.x
|
|
$FieldContent =~ s{
|
|
index[.]pl [?] Action=AgentFAQ [&](amp;)? Subaction=Download [&](amp;)?
|
|
}{public.pl?Action=PublicFAQZoom;Subaction=DownloadAttachment;}gxms;
|
|
|
|
my $HTMLUtilsObject = $Kernel::OM->Get('Kernel::System::HTMLUtils');
|
|
|
|
# convert content to HTML if needed
|
|
if (
|
|
$Kernel::OM->Get('Kernel::Config')->Get('FAQ::Item::HTML')
|
|
&& $LayoutObject->{BrowserRichText}
|
|
&& $FAQData{ContentType} ne 'text/html'
|
|
)
|
|
{
|
|
$FieldContent = $HTMLUtilsObject->ToHTML(
|
|
String => $FieldContent,
|
|
) || '';
|
|
}
|
|
|
|
# add needed HTML headers
|
|
$FieldContent = $HTMLUtilsObject->DocumentComplete(
|
|
String => $FieldContent,
|
|
Charset => 'utf-8',
|
|
);
|
|
|
|
# build base URL for inline images
|
|
my $SessionID = '';
|
|
if ( $Self->{SessionID} && !$Self->{SessionIDCookie} ) {
|
|
$SessionID = ';' . $Self->{SessionName} . '=' . $Self->{SessionID};
|
|
$FieldContent =~ s{
|
|
(Action=PublicFAQZoom;Subaction=DownloadAttachment;ItemID=\d+;FileID=\d+)
|
|
}{$1$SessionID}gmsx;
|
|
}
|
|
|
|
# return complete HTML as an attachment
|
|
return $LayoutObject->Attachment(
|
|
Type => 'inline',
|
|
ContentType => 'text/html',
|
|
Content => $FieldContent,
|
|
);
|
|
}
|
|
|
|
# ---------------------------------------------------------- #
|
|
# DownloadAttachment Sub-action
|
|
# ---------------------------------------------------------- #
|
|
if ( $Self->{Subaction} eq 'DownloadAttachment' ) {
|
|
|
|
# manage parameters
|
|
$GetParam{FileID} = $ParamObject->GetParam( Param => 'FileID' );
|
|
if ( !defined $GetParam{FileID} ) {
|
|
return $LayoutObject->CustomerFatalError(
|
|
Message => Translatable('Need FileID!'),
|
|
);
|
|
}
|
|
|
|
# get attachments
|
|
my %File = $FAQObject->AttachmentGet(
|
|
ItemID => $GetParam{ItemID},
|
|
FileID => $GetParam{FileID},
|
|
UserID => $Self->{UserID},
|
|
);
|
|
if (%File) {
|
|
return $LayoutObject->Attachment(
|
|
%File,
|
|
);
|
|
}
|
|
else {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "No such attachment ($GetParam{FileID})! May be an attack!!!",
|
|
);
|
|
return $LayoutObject->CustomerFatalError();
|
|
}
|
|
}
|
|
|
|
my $Output = $LayoutObject->CustomerHeader(
|
|
Value => $FAQData{Title},
|
|
);
|
|
|
|
# set default interface settings
|
|
my $Interface = $FAQObject->StateTypeGet(
|
|
Name => 'public',
|
|
UserID => $Self->{UserID},
|
|
);
|
|
|
|
# prepare fields data
|
|
FIELD:
|
|
for my $Field (qw(Field1 Field2 Field3 Field4 Field5 Field6)) {
|
|
next FIELD if !$FAQData{$Field};
|
|
|
|
# rewrite links to embedded images for public interface
|
|
if ( $Interface->{Name} eq 'public' ) {
|
|
|
|
# rewrite handle and action
|
|
$FAQData{$Field}
|
|
=~ s{ index[.]pl [?] Action=AgentFAQZoom }{public.pl?Action=PublicFAQZoom}gxms;
|
|
|
|
# take care of old style before FAQ 2.0.x
|
|
$FAQData{$Field} =~ s{
|
|
index[.]pl [?] Action=AgentFAQ [&](amp;)? Subaction=Download [&](amp;)?
|
|
}{public.pl?Action=PublicFAQZoom;Subaction=DownloadAttachment;}gxms;
|
|
}
|
|
|
|
# no quoting if HTML view is enabled
|
|
next FIELD if $ConfigObject->Get('FAQ::Item::HTML');
|
|
|
|
# HTML quoting
|
|
$FAQData{$Field} = $LayoutObject->Ascii2Html(
|
|
NewLine => 0,
|
|
Text => $FAQData{$Field},
|
|
VMax => 5000,
|
|
HTMLResultMode => 1,
|
|
LinkFeature => 1,
|
|
);
|
|
}
|
|
|
|
# set voting results
|
|
$Param{VotingResultColor} = $LayoutObject->GetFAQItemVotingRateColor(
|
|
Rate => $FAQData{VoteResult},
|
|
);
|
|
|
|
if ( !$Param{VotingResultColor} || $FAQData{Votes} eq '0' ) {
|
|
$Param{VotingResultColor} = 'Gray';
|
|
}
|
|
|
|
# show back link
|
|
$LayoutObject->Block(
|
|
Name => 'Back',
|
|
Data => {
|
|
%GetParam,
|
|
%Param,
|
|
%FAQData,
|
|
},
|
|
);
|
|
|
|
# get multi-language option
|
|
my $MultiLanguage = $ConfigObject->Get('FAQ::MultiLanguage');
|
|
|
|
# show language
|
|
if ($MultiLanguage) {
|
|
$LayoutObject->Block(
|
|
Name => 'Language',
|
|
Data => {%FAQData},
|
|
);
|
|
}
|
|
|
|
# get voting default option
|
|
my $Voting = $ConfigObject->Get('FAQ::Voting');
|
|
|
|
# show votes
|
|
if ($Voting) {
|
|
|
|
# always displays Votes result even if its 0
|
|
$LayoutObject->Block(
|
|
Name => 'ViewVotes',
|
|
Data => {%FAQData},
|
|
);
|
|
}
|
|
|
|
# show FAQ path
|
|
my $ShowFAQPath = $LayoutObject->FAQPathShow(
|
|
FAQObject => $FAQObject,
|
|
CategoryID => $FAQData{CategoryID},
|
|
PathForItem => 1,
|
|
UserID => $Self->{UserID},
|
|
);
|
|
if ($ShowFAQPath) {
|
|
$LayoutObject->Block(
|
|
Name => 'FAQPathItemElement',
|
|
Data => {%FAQData},
|
|
);
|
|
}
|
|
|
|
# show keywords as search links
|
|
if ( $FAQData{Keywords} ) {
|
|
|
|
# replace commas and semicolons
|
|
$FAQData{Keywords} =~ s/,/ /g;
|
|
$FAQData{Keywords} =~ s/;/ /g;
|
|
|
|
my @Keywords = split /\s+/, $FAQData{Keywords};
|
|
for my $Keyword (@Keywords) {
|
|
$LayoutObject->Block(
|
|
Name => 'Keywords',
|
|
Data => {
|
|
Keyword => $Keyword,
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
# output rating stars
|
|
if ($Voting) {
|
|
$LayoutObject->FAQRatingStarsShow(
|
|
VoteResult => $FAQData{VoteResult},
|
|
Votes => $FAQData{Votes},
|
|
);
|
|
}
|
|
|
|
# output attachments if any
|
|
my @AttachmentIndex = $FAQObject->AttachmentIndex(
|
|
ItemID => $GetParam{ItemID},
|
|
ShowInline => 0,
|
|
UserID => $Self->{UserID},
|
|
);
|
|
|
|
# output attachments
|
|
if (@AttachmentIndex) {
|
|
$LayoutObject->Block(
|
|
Name => 'AttachmentHeader',
|
|
);
|
|
for my $Attachment (@AttachmentIndex) {
|
|
$LayoutObject->Block(
|
|
Name => 'AttachmentRow',
|
|
Data => {
|
|
%FAQData,
|
|
%{$Attachment},
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
# show FAQ Content
|
|
$LayoutObject->FAQContentShow(
|
|
FAQObject => $FAQObject,
|
|
InterfaceStates => $InterfaceStates,
|
|
FAQData => {%FAQData},
|
|
UserID => $Self->{UserID},
|
|
);
|
|
|
|
# get config of frontend module
|
|
my $Config = $ConfigObject->Get("FAQ::Frontend::$Self->{Action}");
|
|
|
|
# get the dynamic fields for this screen
|
|
my $DynamicField = $Kernel::OM->Get('Kernel::System::DynamicField')->DynamicFieldListGet(
|
|
Valid => 1,
|
|
ObjectType => 'FAQ',
|
|
FieldFilter => $Config->{DynamicField} || {},
|
|
);
|
|
|
|
my $DynamicFieldBackendObject = $Kernel::OM->Get('Kernel::System::DynamicField::Backend');
|
|
|
|
DYNAMICFIELDCONFIG:
|
|
for my $DynamicFieldConfig ( @{$DynamicField} ) {
|
|
next DYNAMICFIELDCONFIG if !IsHashRefWithData($DynamicFieldConfig);
|
|
|
|
my $Value = $DynamicFieldBackendObject->ValueGet(
|
|
DynamicFieldConfig => $DynamicFieldConfig,
|
|
ObjectID => $GetParam{ItemID},
|
|
);
|
|
|
|
# get print string for this dynamic field
|
|
my $ValueStrg = $DynamicFieldBackendObject->DisplayValueRender(
|
|
DynamicFieldConfig => $DynamicFieldConfig,
|
|
Value => $Value,
|
|
ValueMaxChars => 250,
|
|
LayoutObject => $LayoutObject,
|
|
);
|
|
|
|
my $Label = $DynamicFieldConfig->{Label};
|
|
|
|
$LayoutObject->Block(
|
|
Name => 'FAQDynamicField',
|
|
Data => {
|
|
Label => $Label,
|
|
Value => $ValueStrg->{Value},
|
|
Title => $ValueStrg->{Title},
|
|
},
|
|
);
|
|
|
|
# example of dynamic fields order customization
|
|
$LayoutObject->Block(
|
|
Name => 'FAQDynamicField_' . $DynamicFieldConfig->{Name},
|
|
Data => {
|
|
Label => $Label,
|
|
Value => $ValueStrg->{Value},
|
|
Title => $ValueStrg->{Title},
|
|
},
|
|
);
|
|
}
|
|
|
|
# log access to this FAQ item
|
|
$FAQObject->FAQLogAdd(
|
|
ItemID => $ParamObject->GetParam( Param => 'ItemID' ),
|
|
Interface => $Interface->{Name},
|
|
UserID => $Self->{UserID},
|
|
);
|
|
|
|
# start template output
|
|
$Output .= $LayoutObject->Output(
|
|
TemplateFile => 'PublicFAQZoom',
|
|
Data => {
|
|
%FAQData,
|
|
%GetParam,
|
|
%Param,
|
|
},
|
|
);
|
|
|
|
# add footer
|
|
$Output .= $LayoutObject->CustomerFooter();
|
|
|
|
return $Output;
|
|
}
|
|
|
|
1;
|