1972 lines
46 KiB
Perl
1972 lines
46 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::System::FAQ::Category;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use Kernel::System::VariableCheck qw(:all);
|
|
|
|
our @ObjectDependencies = (
|
|
'Kernel::System::Cache',
|
|
'Kernel::System::CustomerGroup',
|
|
'Kernel::System::DB',
|
|
'Kernel::System::Group',
|
|
'Kernel::System::Log',
|
|
'Kernel::System::Valid'
|
|
);
|
|
|
|
=head1 NAME
|
|
|
|
Kernel::System::FAQ::Category - sub module of Kernel::System::FAQ
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
All FAQ category functions.
|
|
|
|
=head1 PUBLIC INTERFACE
|
|
|
|
=head2 CategoryAdd()
|
|
|
|
add a category
|
|
|
|
my $CategoryID = $FAQObject->CategoryAdd(
|
|
Name => 'CategoryA',
|
|
Comment => 'Some comment', # Optional
|
|
ParentID => 2, # Mandatory, but could be 0
|
|
ValidID => 1,
|
|
UserID => 1,
|
|
);
|
|
|
|
Returns:
|
|
|
|
$CategoryID = 34; # or undef if category could not be added
|
|
|
|
=cut
|
|
|
|
sub CategoryAdd {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
for my $Argument (qw(Name UserID ValidID)) {
|
|
if ( !$Param{$Argument} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $Argument!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ( !defined $Param{ParentID} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need ParentID!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
# check that ParentID is not an empty string but number 0 is allowed
|
|
if ( $Param{ParentID} eq '' ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "ParentID cannot be empty!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
|
|
|
# insert record
|
|
return if !$DBObject->Do(
|
|
SQL => '
|
|
INSERT INTO faq_category (name, parent_id, comments, valid_id, created, created_by,
|
|
changed, changed_by)
|
|
VALUES ( ?, ?, ?, ?, current_timestamp, ?, current_timestamp, ?)',
|
|
Bind => [
|
|
\$Param{Name}, \$Param{ParentID}, \$Param{Comment}, \$Param{ValidID},
|
|
\$Param{UserID}, \$Param{UserID},
|
|
],
|
|
);
|
|
|
|
# get new category id
|
|
return if !$DBObject->Prepare(
|
|
SQL => '
|
|
SELECT id
|
|
FROM faq_category
|
|
WHERE name = ? AND parent_id = ?',
|
|
Bind => [ \$Param{Name}, \$Param{ParentID} ],
|
|
Limit => 1,
|
|
);
|
|
|
|
my $CategoryID;
|
|
while ( my @Row = $DBObject->FetchrowArray() ) {
|
|
$CategoryID = $Row[0];
|
|
}
|
|
|
|
# log notice
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'notice',
|
|
Message => "FAQCategory: '$Param{Name}' CategoryID: '$CategoryID' "
|
|
. "created successfully ($Param{UserID})!",
|
|
);
|
|
|
|
return $CategoryID;
|
|
}
|
|
|
|
=head2 CategoryCount()
|
|
|
|
Count the number of categories.
|
|
|
|
my $CategoryCount = $FAQObject->CategoryCount(
|
|
ParentIDs => [ 1, 2, 3, 4 ],
|
|
UserID => 1,
|
|
);
|
|
|
|
Returns:
|
|
|
|
$CategoryCount = 6;
|
|
|
|
=cut
|
|
|
|
sub CategoryCount {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
if ( !$Param{UserID} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => 'Need UserID!',
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
if ( !defined $Param{ParentIDs} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => 'Need ParentIDs!',
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
# build SQL
|
|
my $SQL = '
|
|
SELECT COUNT(*)
|
|
FROM faq_category
|
|
WHERE valid_id IN ('
|
|
. join ', ', $Kernel::OM->Get('Kernel::System::Valid')->ValidIDsGet()
|
|
. ')';
|
|
|
|
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
|
|
|
# parent ids are given
|
|
if ( defined $Param{ParentIDs} ) {
|
|
|
|
# integer quote the parent ids
|
|
for my $ParentID ( @{ $Param{ParentIDs} } ) {
|
|
$ParentID = $DBObject->Quote( $ParentID, 'Integer' );
|
|
}
|
|
|
|
# create string
|
|
my $InString = join ', ', @{ $Param{ParentIDs} };
|
|
|
|
$SQL .= ' AND parent_id IN (' . $InString . ')';
|
|
}
|
|
|
|
# add group by
|
|
$SQL .= ' GROUP BY parent_id';
|
|
|
|
return if !$DBObject->Prepare(
|
|
SQL => $SQL,
|
|
Limit => 200,
|
|
);
|
|
|
|
my $Count = 0;
|
|
while ( my @Row = $DBObject->FetchrowArray() ) {
|
|
$Count = $Row[0];
|
|
}
|
|
|
|
return $Count;
|
|
}
|
|
|
|
=head2 CategoryDelete()
|
|
|
|
Delete a category.
|
|
|
|
my $DeleteSuccess = $FAQObject->CategoryDelete(
|
|
CategoryID => 123,
|
|
UserID => 1,
|
|
);
|
|
|
|
Returns:
|
|
|
|
DeleteSuccess = 1; # or undef if category could not be deleted
|
|
|
|
=cut
|
|
|
|
sub CategoryDelete {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
for my $Attribute (qw(CategoryID UserID)) {
|
|
if ( !$Param{$Attribute} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $Attribute!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
|
|
|
# delete the category
|
|
return if !$DBObject->Do(
|
|
SQL => '
|
|
DELETE FROM faq_category
|
|
WHERE id = ?',
|
|
Bind => [ \$Param{CategoryID} ],
|
|
);
|
|
|
|
# delete the category groups
|
|
return if !$DBObject->Do(
|
|
SQL => '
|
|
DELETE FROM faq_category_group
|
|
WHERE category_id = ?',
|
|
Bind => [ \$Param{CategoryID} ],
|
|
);
|
|
|
|
return 1;
|
|
}
|
|
|
|
=head2 CategoryDuplicateCheck()
|
|
|
|
check a category for duplicate name under the same parent
|
|
|
|
my $Exists = $FAQObject->CategoryDuplicateCheck(
|
|
CategoryID => 1,
|
|
Name => 'Some Name',
|
|
ParentID => 1,
|
|
UserID => 1,
|
|
);
|
|
|
|
Returns:
|
|
|
|
$Exists = 1; # if category name already exists with the same parent
|
|
# or 0 if the name does not exists with the same parent
|
|
|
|
=cut
|
|
|
|
sub CategoryDuplicateCheck {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
if ( !$Param{UserID} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need UserID!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
# set defaults
|
|
$Param{Name} //= '';
|
|
$Param{ParentID} ||= 0;
|
|
my @Values;
|
|
push @Values, \$Param{Name};
|
|
push @Values, \$Param{ParentID};
|
|
|
|
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
|
|
|
# db quote
|
|
$Param{ParentID} = $DBObject->Quote( $Param{ParentID}, 'Integer' );
|
|
|
|
# build SQL
|
|
my $SQL = '
|
|
SELECT id
|
|
FROM faq_category
|
|
WHERE name = ?
|
|
AND parent_id = ?
|
|
';
|
|
if ( defined $Param{CategoryID} ) {
|
|
$SQL .= " AND id != ?";
|
|
push @Values, \$Param{CategoryID};
|
|
|
|
}
|
|
|
|
# prepare SQL statement
|
|
return if !$DBObject->Prepare(
|
|
SQL => $SQL,
|
|
Bind => \@Values,
|
|
Limit => 1,
|
|
);
|
|
|
|
# fetch the result
|
|
my $Exists;
|
|
while ( my @Row = $DBObject->FetchrowArray() ) {
|
|
$Exists = 1;
|
|
}
|
|
|
|
return $Exists;
|
|
}
|
|
|
|
=head2 CategoryGet()
|
|
|
|
get a category as hash
|
|
|
|
my %Category = $FAQObject->CategoryGet(
|
|
CategoryID => 1,
|
|
UserID => 1,
|
|
);
|
|
|
|
Returns:
|
|
|
|
%Category = (,
|
|
CategoryID => 2,
|
|
ParentID => 0,
|
|
Name => 'My Category',
|
|
Comment => 'This is my first category.',
|
|
ValidID => 1,
|
|
);
|
|
|
|
=cut
|
|
|
|
sub CategoryGet {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
if ( !$Param{UserID} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need UserID!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
if ( !defined $Param{CategoryID} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => 'Need CategoryID!',
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
# check cache
|
|
my $CacheKey = 'CategoryGet::' . $Param{CategoryID};
|
|
|
|
# get cache object
|
|
my $CacheObject = $Kernel::OM->Get('Kernel::System::Cache');
|
|
|
|
my $Cache = $CacheObject->Get(
|
|
Type => 'FAQ',
|
|
Key => $CacheKey,
|
|
);
|
|
|
|
return %{$Cache} if $Cache;
|
|
|
|
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
|
|
|
# SQL
|
|
return if !$DBObject->Prepare(
|
|
SQL => '
|
|
SELECT id, parent_id, name, comments, valid_id
|
|
FROM faq_category
|
|
WHERE id = ?',
|
|
Bind => [ \$Param{CategoryID} ],
|
|
Limit => 1,
|
|
);
|
|
|
|
my %Data;
|
|
while ( my @Row = $DBObject->FetchrowArray() ) {
|
|
%Data = (
|
|
CategoryID => $Row[0],
|
|
ParentID => $Row[1],
|
|
Name => $Row[2],
|
|
Comment => $Row[3],
|
|
ValidID => $Row[4],
|
|
);
|
|
}
|
|
|
|
# cache result
|
|
$CacheObject->Set(
|
|
Type => 'FAQ',
|
|
Key => $CacheKey,
|
|
Value => \%Data,
|
|
TTL => 60 * 60 * 24 * 2,
|
|
);
|
|
|
|
return %Data;
|
|
}
|
|
|
|
=head2 CategoryGroupGet()
|
|
|
|
get groups of a category
|
|
|
|
my $GroupArrayRef = $FAQObject->CategoryGroupGet(
|
|
CategoryID => 3,
|
|
UserID => 1,
|
|
);
|
|
|
|
Returns:
|
|
|
|
$GroupArrayRef = [
|
|
2,
|
|
9,
|
|
10,
|
|
];
|
|
|
|
=cut
|
|
|
|
sub CategoryGroupGet {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
for my $Argument (qw(CategoryID UserID)) {
|
|
if ( !$Param{$Argument} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $Argument!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
|
|
|
# get groups
|
|
return if !$DBObject->Prepare(
|
|
SQL => '
|
|
SELECT group_id
|
|
FROM faq_category_group
|
|
WHERE category_id = ?',
|
|
Bind => [ \$Param{CategoryID} ],
|
|
);
|
|
|
|
my @Groups;
|
|
while ( my @Row = $DBObject->FetchrowArray() ) {
|
|
push @Groups, $Row[0];
|
|
}
|
|
|
|
return \@Groups;
|
|
}
|
|
|
|
=head2 CategoryGroupGetAll()
|
|
|
|
get all category-groups
|
|
|
|
my $AllCategoryGroupHashRef = $FAQObject->CategoryGroupGetAll(
|
|
UserID => 1,
|
|
);
|
|
|
|
Returns:
|
|
|
|
$AllCategoryGroupHashRef = {
|
|
1 => {
|
|
2 => 1,
|
|
},
|
|
2 => {
|
|
2 => 1,
|
|
9 => 1,
|
|
10 => 1,
|
|
},
|
|
3 => {
|
|
2 => 1,
|
|
9 => 1,
|
|
10 => 1,
|
|
},
|
|
4 => {
|
|
1 => 1,
|
|
2 => 1,
|
|
3 => 1,
|
|
4 => 1,
|
|
5 => 1,
|
|
9 => 1,
|
|
10 => 1,
|
|
},
|
|
};
|
|
|
|
=cut
|
|
|
|
sub CategoryGroupGetAll {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
if ( !$Param{UserID} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need UserID!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
# check cache
|
|
if ( $Self->{Cache}->{CategoryGroupGetAll} ) {
|
|
|
|
return $Self->{Cache}->{CategoryGroupGetAll};
|
|
}
|
|
|
|
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
|
|
|
# get groups
|
|
return if !$DBObject->Prepare(
|
|
SQL => '
|
|
SELECT group_id, category_id
|
|
FROM faq_category_group',
|
|
);
|
|
|
|
my %Groups;
|
|
while ( my @Row = $DBObject->FetchrowArray() ) {
|
|
$Groups{ $Row[1] }->{ $Row[0] } = 1;
|
|
}
|
|
|
|
# cache
|
|
$Self->{Cache}->{CategoryGroupGetAll} = \%Groups;
|
|
|
|
return \%Groups;
|
|
}
|
|
|
|
=head2 CategoryList()
|
|
|
|
get the category list as hash
|
|
|
|
my $CategoryHashRef = $FAQObject->CategoryList(
|
|
Valid => 1, # (optional)
|
|
UserID => 1,
|
|
);
|
|
|
|
Returns:
|
|
|
|
$CategoryHashRef = {
|
|
0 => {
|
|
1 => 'Misc',
|
|
2 => 'My Category',
|
|
},
|
|
2 => {
|
|
3 => 'Sub Category A',
|
|
4 => 'Sub Category B',
|
|
},
|
|
};
|
|
|
|
=cut
|
|
|
|
sub CategoryList {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
if ( !$Param{UserID} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need UserID!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
# set default
|
|
my $Valid = 0;
|
|
if ( defined $Param{Valid} ) {
|
|
$Valid = $Param{Valid};
|
|
}
|
|
|
|
# check cache
|
|
if ( $Self->{Cache}->{CategoryList}->{$Valid} ) {
|
|
|
|
return $Self->{Cache}->{CategoryList}->{$Valid};
|
|
}
|
|
|
|
# build SQL
|
|
my $SQL = '
|
|
SELECT id, parent_id, name
|
|
FROM faq_category';
|
|
if ($Valid) {
|
|
|
|
# get the valid ids
|
|
$SQL .= ' WHERE valid_id IN ('
|
|
. join ', ', $Kernel::OM->Get('Kernel::System::Valid')->ValidIDsGet()
|
|
. ')';
|
|
}
|
|
|
|
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
|
|
|
# prepare SQL statement
|
|
return if !$DBObject->Prepare( SQL => $SQL );
|
|
|
|
# fetch the result
|
|
my %Data;
|
|
while ( my @Row = $DBObject->FetchrowArray() ) {
|
|
$Data{ $Row[1] }->{ $Row[0] } = $Row[2];
|
|
}
|
|
|
|
# cache
|
|
$Self->{Cache}->{CategoryList}->{$Valid} = \%Data;
|
|
|
|
return \%Data;
|
|
}
|
|
|
|
=head2 CategorySearch()
|
|
|
|
get the category search as an array ref
|
|
|
|
my $CategoryIDArrayRef = $FAQObject->CategorySearch(
|
|
Name => 'Test',
|
|
ParentID => 3,
|
|
ParentIDs => [ 1, 3, 8 ],
|
|
CategoryIDs => [ 2, 5, 7 ],
|
|
OrderBy => 'Name',
|
|
SortBy => 'down',
|
|
UserID => 1,
|
|
);
|
|
|
|
Returns:
|
|
|
|
$CategoryIDArrayRef = [
|
|
2,
|
|
];
|
|
|
|
=cut
|
|
|
|
sub CategorySearch {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
if ( !$Param{UserID} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need UserID!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
# SQL
|
|
my $SQL = '
|
|
SELECT id
|
|
FROM faq_category
|
|
WHERE valid_id IN ('
|
|
. join ', ', $Kernel::OM->Get('Kernel::System::Valid')->ValidIDsGet()
|
|
. ')';
|
|
|
|
my $Ext = '';
|
|
|
|
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
|
|
|
# search for name
|
|
if ( defined $Param{Name} ) {
|
|
|
|
# db like quote
|
|
$Param{Name} = $DBObject->Quote( $Param{Name}, 'Like' );
|
|
|
|
$Ext .= " AND name LIKE '%" . $Param{Name} . "%' $Self->{LikeEscapeString}";
|
|
}
|
|
|
|
# search for parent id
|
|
elsif ( defined $Param{ParentID} ) {
|
|
|
|
# db integer quote
|
|
$Param{ParentID} = $DBObject->Quote( $Param{ParentID}, 'Integer' );
|
|
|
|
$Ext .= ' AND parent_id = ' . $Param{ParentID};
|
|
}
|
|
|
|
# search for parent ids
|
|
elsif (
|
|
defined $Param{ParentIDs}
|
|
&& ref $Param{ParentIDs} eq 'ARRAY'
|
|
&& @{ $Param{ParentIDs} }
|
|
)
|
|
{
|
|
|
|
# integer quote the parent ids
|
|
for my $ParentID ( @{ $Param{ParentIDs} } ) {
|
|
$ParentID = $DBObject->Quote( $ParentID, 'Integer' );
|
|
}
|
|
|
|
# create string
|
|
my $InString = join ', ', @{ $Param{ParentIDs} };
|
|
|
|
$Ext = ' AND parent_id IN (' . $InString . ')';
|
|
}
|
|
|
|
# search for category ids
|
|
elsif (
|
|
defined $Param{CategoryIDs}
|
|
&& ref $Param{CategoryIDs} eq 'ARRAY'
|
|
&& @{ $Param{CategoryIDs} }
|
|
)
|
|
{
|
|
|
|
# integer quote the category ids
|
|
for my $CategoryID ( @{ $Param{CategoryIDs} } ) {
|
|
$CategoryID = $DBObject->Quote( $CategoryID, 'Integer' );
|
|
}
|
|
|
|
# create string
|
|
my $InString = join ', ', @{ $Param{CategoryIDs} };
|
|
|
|
$Ext = ' AND id IN (' . $InString . ')';
|
|
}
|
|
|
|
# ORDER BY
|
|
if ( $Param{OrderBy} ) {
|
|
$Ext .= " ORDER BY name";
|
|
|
|
# set the default sort order
|
|
$Param{SortBy} ||= 'up';
|
|
|
|
# SORT
|
|
if ( $Param{SortBy} ) {
|
|
if ( $Param{SortBy} eq 'up' ) {
|
|
$Ext .= " ASC";
|
|
}
|
|
elsif ( $Param{SortBy} eq 'down' ) {
|
|
$Ext .= " DESC";
|
|
}
|
|
}
|
|
}
|
|
|
|
# SQL STATEMENT
|
|
$SQL .= $Ext;
|
|
|
|
return if !$DBObject->Prepare(
|
|
SQL => $SQL,
|
|
Limit => 500,
|
|
);
|
|
|
|
my @List;
|
|
while ( my @Row = $DBObject->FetchrowArray() ) {
|
|
push @List, $Row[0];
|
|
}
|
|
|
|
return \@List;
|
|
}
|
|
|
|
=head2 CategorySubCategoryIDList()
|
|
|
|
get all subcategory ids of a category
|
|
|
|
my $SubCategoryIDArrayRef = $FAQObject->CategorySubCategoryIDList(
|
|
ParentID => 1,
|
|
Mode => 'Public', # (Agent, Customer, Public)
|
|
CustomerUser => 'tt',
|
|
UserID => 1,
|
|
);
|
|
|
|
Returns:
|
|
|
|
$SubCategoryIDArrayRef = [
|
|
3,
|
|
4,
|
|
5,
|
|
6,
|
|
];
|
|
|
|
=cut
|
|
|
|
sub CategorySubCategoryIDList {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
if ( !$Param{UserID} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need UserID!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
if ( !defined $Param{ParentID} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => 'Need ParentID!',
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
my $Categories = {};
|
|
|
|
if ( $Param{Mode} && $Param{Mode} eq 'Agent' ) {
|
|
|
|
# get agents categories
|
|
$Categories = $Self->GetUserCategories(
|
|
Type => 'ro',
|
|
UserID => $Param{UserID},
|
|
);
|
|
}
|
|
elsif ( $Param{Mode} && $Param{Mode} eq 'Customer' ) {
|
|
|
|
# get customer categories
|
|
$Categories = $Self->GetCustomerCategories(
|
|
Type => 'ro',
|
|
CustomerUser => $Param{CustomerUser},
|
|
UserID => $Param{UserID},
|
|
);
|
|
}
|
|
else {
|
|
|
|
# get all categories
|
|
$Categories = $Self->CategoryList(
|
|
Valid => 1,
|
|
UserID => $Param{UserID},
|
|
);
|
|
}
|
|
|
|
my @SubCategoryIDs;
|
|
my @TempSubCategoryIDs = keys %{ $Categories->{ $Param{ParentID} } };
|
|
SUBCATEGORYID:
|
|
while (@TempSubCategoryIDs) {
|
|
|
|
# get next subcategory id
|
|
my $SubCategoryID = shift @TempSubCategoryIDs;
|
|
|
|
# add to result
|
|
push @SubCategoryIDs, $SubCategoryID;
|
|
|
|
# check if subcategory has own subcategories
|
|
next SUBCATEGORYID if !$Categories->{$SubCategoryID};
|
|
|
|
# add new subcategories
|
|
push @TempSubCategoryIDs, keys %{ $Categories->{$SubCategoryID} };
|
|
}
|
|
|
|
# sort subcategories numerically
|
|
@SubCategoryIDs = sort { $a <=> $b } @SubCategoryIDs;
|
|
|
|
return \@SubCategoryIDs;
|
|
}
|
|
|
|
=head2 CategoryTreeList()
|
|
|
|
get all categories as tree (with their long names)
|
|
|
|
my $CategoryTree = $FAQObject->CategoryTreeList(
|
|
Valid => 0, # (0|1, optional)
|
|
UserID => 1,
|
|
);
|
|
|
|
Returns:
|
|
|
|
$CategoryTree = {
|
|
1 => 'Misc',
|
|
2 => 'My Category',
|
|
3 => 'My Category::Sub Category A',
|
|
4 => 'My Category::Sub Category B',
|
|
};
|
|
|
|
=cut
|
|
|
|
sub CategoryTreeList {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
if ( !$Param{UserID} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need UserID!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
# set default
|
|
my $Valid = 0;
|
|
if ( $Param{Valid} ) {
|
|
$Valid = $Param{Valid};
|
|
}
|
|
|
|
# check cache
|
|
if ( $Self->{Cache}->{GetCategoryTree}->{$Valid} ) {
|
|
|
|
return $Self->{Cache}->{GetCategoryTree}->{$Valid};
|
|
}
|
|
|
|
# build SQL
|
|
my $SQL = '
|
|
SELECT id, parent_id, name
|
|
FROM faq_category';
|
|
|
|
# add where clause for valid categories
|
|
if ($Valid) {
|
|
$SQL .= ' WHERE valid_id IN ('
|
|
. join ', ', $Kernel::OM->Get('Kernel::System::Valid')->ValidIDsGet()
|
|
. ')';
|
|
}
|
|
|
|
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
|
|
|
# prepare SQL
|
|
return if !$DBObject->Prepare(
|
|
SQL => $SQL,
|
|
);
|
|
|
|
# fetch result
|
|
my %CategoryMap;
|
|
my %CategoryNameLookup;
|
|
my %ParentIDLookup;
|
|
while ( my @Row = $DBObject->FetchrowArray() ) {
|
|
$CategoryMap{ $Row[1] }->{ $Row[0] } = $Row[2];
|
|
$CategoryNameLookup{ $Row[0] } = $Row[2];
|
|
$ParentIDLookup{ $Row[0] } = $Row[1];
|
|
}
|
|
|
|
# to store the category tree
|
|
my %CategoryTree;
|
|
|
|
# check all parent IDs
|
|
for my $ParentID ( sort { $a <=> $b } keys %CategoryMap ) {
|
|
|
|
# get subcategories and names for this parent id
|
|
while ( my ( $CategoryID, $CategoryName ) = each %{ $CategoryMap{$ParentID} } ) {
|
|
|
|
# lookup the parents name
|
|
my $NewParentID = $ParentID;
|
|
while ($NewParentID) {
|
|
|
|
# pre-append parents category name
|
|
if ( $CategoryNameLookup{$NewParentID} ) {
|
|
$CategoryName = $CategoryNameLookup{$NewParentID} . '::' . $CategoryName;
|
|
}
|
|
|
|
# get up one parent level
|
|
$NewParentID = $ParentIDLookup{$NewParentID} || 0;
|
|
}
|
|
|
|
# add category to tree
|
|
$CategoryTree{$CategoryID} = $CategoryName;
|
|
}
|
|
}
|
|
|
|
# cache
|
|
$Self->{Cache}->{GetCategoryTree}->{$Valid} = \%CategoryTree;
|
|
|
|
return \%CategoryTree;
|
|
}
|
|
|
|
=head2 CategoryUpdate()
|
|
|
|
update a category
|
|
|
|
my $Success = $FAQObject->CategoryUpdate(
|
|
CategoryID => 2,
|
|
ParentID => 1,
|
|
Name => 'Some Category',
|
|
Comment => 'some comment',
|
|
UserID => 1,
|
|
);
|
|
|
|
Returns:
|
|
|
|
$Success = 1; # or undef if category could not be updated
|
|
|
|
=cut
|
|
|
|
sub CategoryUpdate {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
for my $Argument (qw(Name UserID)) {
|
|
if ( !$Param{$Argument} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $Argument!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
for my $Argument (qw(CategoryID ParentID)) {
|
|
if ( !defined $Param{$Argument} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $Argument!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
# check that ParentID is not an empty string but number 0 is allowed
|
|
if ( $Param{ParentID} eq '' ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "ParentID cannot be empty!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
|
|
|
# SQL
|
|
return if !$DBObject->Do(
|
|
SQL => '
|
|
UPDATE faq_category
|
|
SET parent_id = ?, name = ?, comments = ?, valid_id = ?, changed = current_timestamp,
|
|
changed_by = ?
|
|
WHERE id = ?',
|
|
Bind => [
|
|
\$Param{ParentID}, \$Param{Name},
|
|
\$Param{Comment}, \$Param{ValidID},
|
|
\$Param{UserID}, \$Param{CategoryID},
|
|
],
|
|
);
|
|
|
|
# log notice
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'notice',
|
|
Message => "FAQCategory: '$Param{Name}' "
|
|
. "ID: '$Param{CategoryID}' updated successfully ($Param{UserID})!",
|
|
);
|
|
|
|
# delete all cache, as FAQGet() will be also affected.
|
|
$Kernel::OM->Get('Kernel::System::Cache')->CleanUp(
|
|
Type => 'FAQ',
|
|
);
|
|
|
|
return 1;
|
|
}
|
|
|
|
=head2 AgentCategorySearch()
|
|
|
|
get the category search as array ref
|
|
|
|
my $CategoryIDArrayRef = $FAQObject->AgentCategorySearch(
|
|
ParentID => 3, # (optional, default 0)
|
|
GetSubCategories => 1, # (optional, default 0)
|
|
UserID => 1,
|
|
);
|
|
|
|
Returns:
|
|
|
|
$CategoryIDArrayRef = [
|
|
'4',
|
|
'8',
|
|
];
|
|
|
|
=cut
|
|
|
|
sub AgentCategorySearch {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
if ( !$Param{UserID} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => 'Need UserID!',
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
# set default parent id
|
|
my $ParentID = $Param{ParentID} ? $Param{ParentID} : 0;
|
|
|
|
my $Categories = $Self->GetUserCategories(
|
|
Type => 'ro',
|
|
UserID => $Param{UserID},
|
|
);
|
|
|
|
return [] if !IsHashRefWithData($Categories);
|
|
|
|
my %Category = %{ $Categories->{$ParentID} };
|
|
my @CategoryIDs = sort { $Category{$a} cmp $Category{$b} } ( keys %Category );
|
|
|
|
return \@CategoryIDs if !$Param{GetSubCategories};
|
|
|
|
# Check if some IDs have a subcategory and add this also to the list.
|
|
for my $CategoryID (@CategoryIDs) {
|
|
|
|
# get all subcategory ids for this category
|
|
my $SubCategoryIDs = $Self->CategorySubCategoryIDList(
|
|
ParentID => $CategoryID,
|
|
Mode => 'Agent',
|
|
UserID => $Param{UserID},
|
|
);
|
|
|
|
# Add the sub categories to the category ids.
|
|
push @CategoryIDs, @{$SubCategoryIDs};
|
|
}
|
|
|
|
# Remove any duplicate IDs from the lest
|
|
my %Seen;
|
|
@CategoryIDs = grep { !$Seen{$_}++ } @CategoryIDs;
|
|
|
|
return \@CategoryIDs;
|
|
}
|
|
|
|
=head2 CustomerCategorySearch()
|
|
|
|
get the category search as hash
|
|
|
|
my $CategoryIDArrayRef = @{$FAQObject->CustomerCategorySearch(
|
|
CustomerUser => 'tt',
|
|
ParentID => 3, # (optional, default 0)
|
|
GetSubCategories => 1, # (optional, default 0)
|
|
Mode => 'Customer',
|
|
UserID => 1,
|
|
)};
|
|
|
|
Returns:
|
|
|
|
$CategoryIDArrayRef = [
|
|
'4',
|
|
'8',
|
|
];
|
|
|
|
=cut
|
|
|
|
sub CustomerCategorySearch {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
for my $Argument (qw(CustomerUser Mode UserID)) {
|
|
if ( !$Param{$Argument} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $Argument!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
# set default parent id
|
|
my $ParentID = $Param{ParentID} ? $Param{ParentID} : 0;
|
|
|
|
my $Categories = $Self->GetCustomerCategories(
|
|
CustomerUser => $Param{CustomerUser},
|
|
Type => 'ro',
|
|
UserID => $Param{UserID},
|
|
);
|
|
|
|
my %Category = %{ $Categories->{$ParentID} };
|
|
my @CategoryIDs = sort { $Category{$a} cmp $Category{$b} } ( keys %Category );
|
|
|
|
my @AllowedCategoryIDs;
|
|
my %Articles;
|
|
|
|
# check cache
|
|
my $CacheKey = 'CustomerCategorySearch::Articles';
|
|
if ( $Self->{Cache}->{$CacheKey} ) {
|
|
%Articles = %{ $Self->{Cache}->{$CacheKey} };
|
|
}
|
|
else {
|
|
|
|
# build valid id string
|
|
my $ValidIDsString = join ', ', $Kernel::OM->Get('Kernel::System::Valid')->ValidIDsGet();
|
|
|
|
my $SQL = "
|
|
SELECT faq_item.id, faq_item.category_id
|
|
FROM faq_item, faq_state_type, faq_state
|
|
WHERE faq_state.id = faq_item.state_id
|
|
AND faq_state.type_id = faq_state_type.id
|
|
AND faq_state_type.name != 'internal'
|
|
AND faq_item.valid_id IN ($ValidIDsString)
|
|
AND faq_item.approved = 1";
|
|
|
|
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
|
|
|
return if !$DBObject->Prepare(
|
|
SQL => $SQL,
|
|
);
|
|
while ( my @Row = $DBObject->FetchrowArray() ) {
|
|
$Articles{ $Row[1] }++;
|
|
}
|
|
|
|
# cache
|
|
$Self->{Cache}->{$CacheKey} = \%Articles;
|
|
}
|
|
|
|
return \@CategoryIDs if !$Param{GetSubCategories};
|
|
|
|
for my $CategoryID (@CategoryIDs) {
|
|
|
|
# get all subcategory ids for this category
|
|
my $SubCategoryIDs = $Self->CategorySubCategoryIDList(
|
|
ParentID => $CategoryID,
|
|
Mode => $Param{Mode},
|
|
CustomerUser => $Param{CustomerUser},
|
|
UserID => $Param{UserID},
|
|
);
|
|
|
|
# add this category id
|
|
my @IDs = ( $CategoryID, @{$SubCategoryIDs} );
|
|
|
|
# check if category contains articles with state external or public
|
|
ID:
|
|
for my $ID (@IDs) {
|
|
next ID if !$Articles{$ID};
|
|
push @AllowedCategoryIDs, $ID;
|
|
}
|
|
}
|
|
|
|
return \@AllowedCategoryIDs;
|
|
}
|
|
|
|
=head2 PublicCategorySearch()
|
|
|
|
get the category search as hash
|
|
|
|
my $CategoryIDArrayRef = $FAQObject->PublicCategorySearch(
|
|
ParentID => 3, # (optional, default 0)
|
|
Mode => 'Public',
|
|
UserID => 1,
|
|
);
|
|
|
|
Returns:
|
|
|
|
$CategoryIDArrayRef = [
|
|
'4',
|
|
'8',
|
|
];
|
|
|
|
=cut
|
|
|
|
sub PublicCategorySearch {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
for my $Argument (qw(Mode UserID)) {
|
|
if ( !$Param{$Argument} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $Argument!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ( !defined $Param{ParentID} ) {
|
|
$Param{ParentID} = 0;
|
|
}
|
|
|
|
my $CategoryListCategories = $Self->CategoryList(
|
|
Valid => 1,
|
|
UserID => $Param{UserID},
|
|
);
|
|
|
|
return [] if !$CategoryListCategories->{ $Param{ParentID} };
|
|
|
|
my %Category = %{ $CategoryListCategories->{ $Param{ParentID} } };
|
|
my @CategoryIDs = sort { $Category{$a} cmp $Category{$b} } ( keys %Category );
|
|
my @AllowedCategoryIDs;
|
|
|
|
# build valid id string
|
|
my $ValidIDsString = join ', ', $Kernel::OM->Get('Kernel::System::Valid')->ValidIDsGet();
|
|
|
|
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
|
|
|
for my $CategoryID (@CategoryIDs) {
|
|
|
|
# get all subcategory ids for this category
|
|
my $SubCategoryIDs = $Self->CategorySubCategoryIDList(
|
|
ParentID => $CategoryID,
|
|
Mode => $Param{Mode},
|
|
CustomerUser => $Param{CustomerUser},
|
|
UserID => $Param{UserID},
|
|
);
|
|
|
|
# add this category id
|
|
my @IDs = ( $CategoryID, @{$SubCategoryIDs} );
|
|
|
|
# check if category contains articles with state public
|
|
my $FoundArticle = 0;
|
|
|
|
my $SQL = "
|
|
SELECT faq_item.id
|
|
FROM faq_item, faq_state_type, faq_state
|
|
WHERE faq_item.category_id = ?
|
|
AND faq_item.valid_id IN ($ValidIDsString)
|
|
AND faq_state.id = faq_item.state_id
|
|
AND faq_state.type_id = faq_state_type.id
|
|
AND faq_state_type.name = 'public'
|
|
AND faq_item.approved = 1";
|
|
|
|
ID:
|
|
for my $ID (@IDs) {
|
|
|
|
return if !$DBObject->Prepare(
|
|
SQL => $SQL,
|
|
Bind => [ \$ID ],
|
|
Limit => 1,
|
|
);
|
|
while ( my @Row = $DBObject->FetchrowArray() ) {
|
|
$FoundArticle = $Row[0];
|
|
}
|
|
last ID if $FoundArticle;
|
|
}
|
|
|
|
# an article was found
|
|
if ($FoundArticle) {
|
|
push @AllowedCategoryIDs, $CategoryID;
|
|
}
|
|
}
|
|
|
|
return \@AllowedCategoryIDs;
|
|
|
|
}
|
|
|
|
=head2 GetUserCategories()
|
|
|
|
get user category-groups
|
|
|
|
my $UserCategoryGroupHashRef = $FAQObject->GetUserCategories(
|
|
Type => 'rw',
|
|
UserID => 1,
|
|
);
|
|
|
|
Returns:
|
|
|
|
$UserCategoryGroupHashRef = {
|
|
1 => {},
|
|
0 => {
|
|
1 => 'Misc',
|
|
2 => 'My Category',
|
|
},
|
|
2 => {
|
|
3 => 'Sub Category A',
|
|
4 => 'Sub Category B',
|
|
},
|
|
3 => {},
|
|
4 => {},
|
|
};
|
|
|
|
=cut
|
|
|
|
sub GetUserCategories {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
for my $Argument (qw(Type UserID)) {
|
|
if ( !$Param{$Argument} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $Argument!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
my $Categories = $Self->CategoryList(
|
|
Valid => 1,
|
|
UserID => $Param{UserID},
|
|
);
|
|
|
|
my $CategoryGroups = $Self->CategoryGroupGetAll(
|
|
UserID => $Param{UserID},
|
|
);
|
|
|
|
my %UserGroups = $Kernel::OM->Get('Kernel::System::Group')->GroupMemberList(
|
|
UserID => $Param{UserID},
|
|
Type => $Param{Type},
|
|
Result => 'HASH',
|
|
);
|
|
|
|
my $UserCategories = $Self->_UserCategories(
|
|
Categories => $Categories,
|
|
CategoryGroups => $CategoryGroups,
|
|
UserGroups => \%UserGroups,
|
|
UserID => $Param{UserID},
|
|
);
|
|
|
|
return $UserCategories;
|
|
}
|
|
|
|
=head2 GetUserCategoriesLongNames()
|
|
|
|
get user category-groups (show category long names)
|
|
|
|
my $UserCategoryGroupHashRef = $FAQObject->GetUserCategoriesLongNames(
|
|
Type => 'rw',
|
|
UserID => 1,
|
|
);
|
|
|
|
Returns:
|
|
|
|
$UserCategoryGroupHashRef = {
|
|
1 => 'Misc',
|
|
2 => 'My Category',
|
|
3 => 'My Category::Sub Category A',
|
|
4 => 'My Category::Sub Category A',
|
|
};
|
|
|
|
=cut
|
|
|
|
sub GetUserCategoriesLongNames {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
for my $Argument (qw(Type UserID)) {
|
|
if ( !$Param{$Argument} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $Argument!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
# get categories where user has rights
|
|
my $UserCategories = $Self->GetUserCategories(
|
|
Type => $Param{Type},
|
|
UserID => $Param{UserID},
|
|
);
|
|
|
|
# get all categories with their long names
|
|
my $CategoryTree = $Self->CategoryTreeList(
|
|
Valid => 1,
|
|
UserID => $Param{UserID},
|
|
);
|
|
|
|
# to store the user categories with their long names
|
|
my %UserCategoriesLongNames;
|
|
|
|
# get the long names of the categories where user has rights
|
|
PARENTID:
|
|
for my $ParentID ( sort keys %{$UserCategories} ) {
|
|
|
|
next PARENTID if !$UserCategories->{$ParentID};
|
|
next PARENTID if ref $UserCategories->{$ParentID} ne 'HASH';
|
|
next PARENTID if !%{ $UserCategories->{$ParentID} };
|
|
|
|
for my $CategoryID ( sort keys %{ $UserCategories->{$ParentID} } ) {
|
|
$UserCategoriesLongNames{$CategoryID} = $CategoryTree->{$CategoryID};
|
|
}
|
|
}
|
|
|
|
return \%UserCategoriesLongNames;
|
|
}
|
|
|
|
=head2 GetCustomerCategories()
|
|
|
|
get customer user categories
|
|
|
|
my $CustomerUserCategoryHashRef = $FAQObject->GetCustomerCategories(
|
|
CustomerUser => 'hans',
|
|
Type => 'rw',
|
|
UserID => 1,
|
|
);
|
|
|
|
Returns:
|
|
|
|
$CustomerUserCategoryHashRef = {
|
|
1 => {},
|
|
0 => {
|
|
1 => 'Misc',
|
|
2 => 'My Category',
|
|
},
|
|
2 => {
|
|
3 => 'Sub Category A',
|
|
4 => 'Sub Category B',
|
|
},
|
|
3 => {},
|
|
4 => {},
|
|
};
|
|
|
|
=cut
|
|
|
|
sub GetCustomerCategories {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
for my $Argument (qw(CustomerUser Type UserID)) {
|
|
if ( !$Param{$Argument} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $Argument!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
# check cache
|
|
my $CacheKey = 'GetCustomerCategories::CustomerUser::' . $Param{CustomerUser};
|
|
if ( defined $Self->{Cache}->{$CacheKey} ) {
|
|
return $Self->{Cache}->{$CacheKey};
|
|
}
|
|
|
|
# get all valid categories
|
|
my $Categories = $Self->CategoryList(
|
|
Valid => 1,
|
|
UserID => $Param{UserID},
|
|
);
|
|
|
|
my $CategoryGroups = $Self->CategoryGroupGetAll(
|
|
UserID => $Param{UserID},
|
|
);
|
|
|
|
my %UserGroups = $Kernel::OM->Get('Kernel::System::CustomerGroup')->GroupMemberList(
|
|
UserID => $Param{CustomerUser},
|
|
Type => 'ro',
|
|
Result => 'HASH',
|
|
);
|
|
|
|
my $CustomerCategories = $Self->_UserCategories(
|
|
Categories => $Categories,
|
|
CategoryGroups => $CategoryGroups,
|
|
UserGroups => \%UserGroups,
|
|
UserID => $Param{UserID},
|
|
);
|
|
|
|
# cache
|
|
$Self->{Cache}->{$CacheKey} = $CustomerCategories;
|
|
|
|
return $CustomerCategories;
|
|
}
|
|
|
|
=head2 GetCustomerCategoriesLongNames()
|
|
|
|
get customer category-groups (show category long names)
|
|
|
|
my $CustomerCategoryGroupHashRef = $FAQObject->GetCustomerCategoriesLongNames(
|
|
CustomerUser => 'hans',
|
|
Type => 'rw',
|
|
UserID => 1,
|
|
);
|
|
|
|
Returns:
|
|
|
|
$CustomerCategoryGroupHashRef = {
|
|
1 => 'Misc',
|
|
2 => 'My Category',
|
|
3 => 'My Category::Sub Category A',
|
|
4 => 'My Category::Sub Category A',
|
|
};
|
|
|
|
=cut
|
|
|
|
sub GetCustomerCategoriesLongNames {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
for my $Argument (qw(CustomerUser Type UserID)) {
|
|
if ( !$Param{$Argument} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $Argument!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
# get categories where user has rights
|
|
my $CustomerCategories = $Self->GetCustomerCategories(
|
|
CustomerUser => $Param{CustomerUser},
|
|
Type => $Param{Type},
|
|
UserID => $Param{UserID},
|
|
);
|
|
|
|
# extract category ids
|
|
my %AllCategoryIDs;
|
|
for my $ParentID ( sort keys %{$CustomerCategories} ) {
|
|
for my $CategoryID ( sort keys %{ $CustomerCategories->{$ParentID} } ) {
|
|
$AllCategoryIDs{$CategoryID} = 1;
|
|
}
|
|
}
|
|
|
|
# get all customer category ids
|
|
my @CustomerCategoryIDs;
|
|
for my $CategoryID ( 0, keys %AllCategoryIDs ) {
|
|
push @CustomerCategoryIDs, @{
|
|
$Self->CustomerCategorySearch(
|
|
ParentID => $CategoryID,
|
|
CustomerUser => $Param{CustomerUser},
|
|
Mode => 'Customer',
|
|
UserID => $Param{UserID},
|
|
)
|
|
};
|
|
}
|
|
|
|
# build customer category hash
|
|
$CustomerCategories = {};
|
|
for my $CategoryID (@CustomerCategoryIDs) {
|
|
my %Category = $Self->CategoryGet(
|
|
CategoryID => $CategoryID,
|
|
UserID => $Param{UserID},
|
|
);
|
|
$CustomerCategories->{ $Category{ParentID} }->{ $Category{CategoryID} } = $Category{Name};
|
|
}
|
|
|
|
# get all categories with their long names
|
|
my $CategoryTree = $Self->CategoryTreeList(
|
|
Valid => 1,
|
|
UserID => $Param{UserID},
|
|
);
|
|
|
|
# to store the user categories with their long names
|
|
my %CustomerCategoriesLongNames;
|
|
|
|
# get the long names of the categories where user has rights
|
|
PARENTID:
|
|
for my $ParentID ( sort keys %{$CustomerCategories} ) {
|
|
|
|
next PARENTID if !$CustomerCategories->{$ParentID};
|
|
next PARENTID if ref $CustomerCategories->{$ParentID} ne 'HASH';
|
|
next PARENTID if !%{ $CustomerCategories->{$ParentID} };
|
|
|
|
for my $CategoryID ( sort keys %{ $CustomerCategories->{$ParentID} } ) {
|
|
$CustomerCategoriesLongNames{$CategoryID} = $CategoryTree->{$CategoryID};
|
|
}
|
|
}
|
|
|
|
return \%CustomerCategoriesLongNames;
|
|
}
|
|
|
|
=head2 GetPublicCategoriesLongNames()
|
|
|
|
get public category-groups (show category long names)
|
|
|
|
my $PublicCategoryGroupHashRef = $FAQObject->GetPublicCategoriesLongNames(
|
|
Type => 'rw',
|
|
UserID => 1,
|
|
);
|
|
|
|
Returns:
|
|
|
|
$PublicCategoryGroupHashRef = {
|
|
1 => 'Misc',
|
|
2 => 'My Category',
|
|
3 => 'My Category::Sub Category A',
|
|
4 => 'My Category::Sub Category A',
|
|
};
|
|
|
|
=cut
|
|
|
|
sub GetPublicCategoriesLongNames {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
for my $Argument (qw(Type UserID)) {
|
|
if ( !$Param{$Argument} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $Argument!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
# get all categories
|
|
my $PublicCategories = $Self->CategoryList( UserID => $Param{UserID} );
|
|
|
|
# extract category ids
|
|
my %AllCategoryIDs;
|
|
for my $ParentID ( sort keys %{$PublicCategories} ) {
|
|
for my $CategoryID ( sort keys %{ $PublicCategories->{$ParentID} } ) {
|
|
$AllCategoryIDs{$CategoryID} = 1;
|
|
}
|
|
}
|
|
|
|
# get all public category ids
|
|
my @PublicCategoryIDs;
|
|
for my $CategoryID ( 0, keys %AllCategoryIDs ) {
|
|
push @PublicCategoryIDs, @{
|
|
$Self->PublicCategorySearch(
|
|
ParentID => $CategoryID,
|
|
Mode => 'Public',
|
|
UserID => $Param{UserID},
|
|
)
|
|
};
|
|
}
|
|
|
|
# build public category hash
|
|
$PublicCategories = {};
|
|
for my $CategoryID (@PublicCategoryIDs) {
|
|
my %Category = $Self->CategoryGet(
|
|
CategoryID => $CategoryID,
|
|
UserID => $Param{UserID},
|
|
);
|
|
$PublicCategories->{ $Category{ParentID} }->{ $Category{CategoryID} } = $Category{Name};
|
|
}
|
|
|
|
# get all categories with their long names
|
|
my $CategoryTree = $Self->CategoryTreeList(
|
|
Valid => 1,
|
|
UserID => $Param{UserID},
|
|
);
|
|
|
|
# to store the user categories with their long names
|
|
my %PublicCategoriesLongNames;
|
|
|
|
# get the long names of the categories where user has rights
|
|
PARENTID:
|
|
for my $ParentID ( sort keys %{$PublicCategories} ) {
|
|
|
|
next PARENTID if !$PublicCategories->{$ParentID};
|
|
next PARENTID if ref $PublicCategories->{$ParentID} ne 'HASH';
|
|
next PARENTID if !%{ $PublicCategories->{$ParentID} };
|
|
|
|
for my $CategoryID ( sort keys %{ $PublicCategories->{$ParentID} } ) {
|
|
$PublicCategoriesLongNames{$CategoryID} = $CategoryTree->{$CategoryID};
|
|
}
|
|
}
|
|
|
|
return \%PublicCategoriesLongNames;
|
|
}
|
|
|
|
=head2 CheckCategoryUserPermission()
|
|
|
|
get user permission for a category
|
|
|
|
my $PermissionString = $FAQObject->CheckCategoryUserPermission(
|
|
CategoryID => '123',
|
|
Type => 'rw', # (optional) rw or ro, default ro
|
|
UserID => 1,
|
|
);
|
|
|
|
Returns:
|
|
|
|
$PermissionString = 'rw'; # or 'ro' or ''
|
|
|
|
=cut
|
|
|
|
sub CheckCategoryUserPermission {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
for my $Argument (qw(CategoryID UserID)) {
|
|
if ( !$Param{$Argument} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $Argument!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ( !$Param{Type} ) {
|
|
$Param{Type} = 'ro';
|
|
}
|
|
|
|
$Param{Type} = lc $Param{Type};
|
|
|
|
if ( $Param{Type} ne 'rw' && $Param{Type} ne 'ro' ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Type is invalid!",
|
|
);
|
|
}
|
|
|
|
my $UserCategories = $Self->GetUserCategories(
|
|
Type => $Param{Type},
|
|
UserID => $Param{UserID},
|
|
);
|
|
|
|
for my $ParentID ( sort keys %{$UserCategories} ) {
|
|
my $Categories = $UserCategories->{$ParentID};
|
|
for my $CategoryID ( sort keys %{$Categories} ) {
|
|
if ( $CategoryID == $Param{CategoryID} ) {
|
|
|
|
return $Param{Type};
|
|
}
|
|
}
|
|
}
|
|
|
|
return '';
|
|
}
|
|
|
|
=head2 CheckCategoryCustomerPermission()
|
|
|
|
get customer user permission for a category
|
|
|
|
my $PermissionString $FAQObject->CheckCategoryCustomerPermission(
|
|
CustomerUser => 'mm',
|
|
CategoryID => '123',
|
|
UserID => 1,
|
|
);
|
|
|
|
Returns:
|
|
|
|
$PermissionString = 'rw'; # or 'ro' or ''
|
|
|
|
=cut
|
|
|
|
sub CheckCategoryCustomerPermission {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
for my $Argument (qw(CustomerUser CategoryID UserID)) {
|
|
if ( !$Param{$Argument} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $Argument!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
for my $Permission (qw(rw ro)) {
|
|
my $CustomerCategories = $Self->GetCustomerCategories(
|
|
CustomerUser => $Param{CustomerUser},
|
|
Type => 'ro',
|
|
UserID => $Param{UserID},
|
|
);
|
|
for my $ParentID ( sort keys %{$CustomerCategories} ) {
|
|
my $Categories = $CustomerCategories->{$ParentID};
|
|
for my $CategoryID ( sort keys %{$Categories} ) {
|
|
if ( $CategoryID == $Param{CategoryID} ) {
|
|
|
|
return $Permission;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return '';
|
|
}
|
|
|
|
=head2 SetCategoryGroup()
|
|
|
|
set groups to a category
|
|
|
|
my $Success = $FAQObject->SetCategoryGroup(
|
|
CategoryID => 3,
|
|
GroupIDs => [ 2,4,1,5,77 ],
|
|
UserID => 1,
|
|
);
|
|
|
|
Returns:
|
|
|
|
$Success = 1; # or undef if groups could not be set to a category
|
|
|
|
=cut
|
|
|
|
sub SetCategoryGroup {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
for my $Argument (qw(CategoryID GroupIDs UserID)) {
|
|
if ( !$Param{$Argument} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $Argument!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
|
|
|
# delete old groups
|
|
return if !$DBObject->Do(
|
|
SQL => '
|
|
DELETE FROM faq_category_group
|
|
WHERE category_id = ?',
|
|
Bind => [ \$Param{CategoryID} ],
|
|
);
|
|
|
|
# insert groups
|
|
$Param{CategoryID} = $DBObject->Quote( $Param{CategoryID}, 'Integer' );
|
|
for my $GroupID ( @{ $Param{GroupIDs} } ) {
|
|
|
|
# db quote
|
|
$GroupID = $DBObject->Quote( $GroupID, 'Integer' );
|
|
|
|
my $SQL = "
|
|
INSERT INTO faq_category_group (category_id, group_id, changed, changed_by, created,
|
|
created_by)
|
|
VALUES ($Param{CategoryID}, $GroupID, current_timestamp, $Param{UserID},
|
|
current_timestamp, $Param{UserID})";
|
|
|
|
# write attachment to db
|
|
return if !$DBObject->Do( SQL => $SQL );
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
=head1 PRIVATE FUNCTIONS
|
|
|
|
=head2 _UserCategories()
|
|
|
|
reduces the categories ( from CategoryList() ) to only the ones where the user has privileges.
|
|
|
|
my $UserCategories = $FAQObject->_UserCategories(
|
|
Categories => $CategoryHashRef, # as returned form CategoryList()
|
|
CategoryGroups => $CategoryGroupHashRef, # as returned from CategoryGroupGetAll
|
|
UserGroups => $UserGroupsHashRef,
|
|
UserID => 123,
|
|
);
|
|
|
|
Returns:
|
|
|
|
$UserCategoies = {
|
|
0 => {
|
|
1 => 'Misc',
|
|
2 => 'My Category',
|
|
},
|
|
2 => {
|
|
3 => 'Sub Category A',
|
|
},
|
|
};
|
|
|
|
=cut
|
|
|
|
sub _UserCategories {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
for my $Argument (qw(Categories UserID)) {
|
|
if ( !$Param{$Argument} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $Argument!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
my %UserCategories;
|
|
|
|
PARENTID:
|
|
for my $ParentID ( sort { $a <=> $b } keys %{ $Param{Categories} } ) {
|
|
|
|
my %SubCategories;
|
|
|
|
CATEGORYID:
|
|
for my $CategoryID ( sort keys %{ $Param{Categories}->{$ParentID} } ) {
|
|
|
|
# check category groups
|
|
next CATEGORYID if !defined $Param{CategoryGroups}->{$CategoryID};
|
|
|
|
# check user groups
|
|
GROUPID:
|
|
for my $GroupID ( sort keys %{ $Param{CategoryGroups}->{$CategoryID} } ) {
|
|
|
|
next GROUPID if !defined $Param{UserGroups}->{$GroupID};
|
|
|
|
# add category
|
|
$SubCategories{$CategoryID} = $Param{Categories}->{$ParentID}->{$CategoryID};
|
|
|
|
# add empty hash if category has no subcategories
|
|
if ( !$UserCategories{$CategoryID} ) {
|
|
$UserCategories{$CategoryID} = {};
|
|
}
|
|
|
|
last GROUPID;
|
|
}
|
|
}
|
|
|
|
$UserCategories{$ParentID} = \%SubCategories;
|
|
}
|
|
|
|
return \%UserCategories;
|
|
}
|
|
|
|
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
|