# --
# 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::ProcessManagement::DB::Activity;
use strict;
use warnings;
use Kernel::System::VariableCheck qw(:all);
our @ObjectDependencies = (
'Kernel::Config',
'Kernel::System::Cache',
'Kernel::System::DB',
'Kernel::System::Log',
'Kernel::System::ProcessManagement::DB::ActivityDialog',
'Kernel::System::YAML',
);
=head1 NAME
Kernel::System::ProcessManagement::DB::Activity
=head1 DESCRIPTION
Process Management DB Activity backend
=head1 PUBLIC INTERFACE
=head2 new()
Don't use the constructor directly, use the ObjectManager instead:
my $ActivityObject = $Kernel::OM->Get('Kernel::System::ProcessManagement::DB::Activity');
=cut
sub new {
my ( $Type, %Param ) = @_;
# allocate new hash for object
my $Self = {};
bless( $Self, $Type );
# get the cache TTL (in seconds)
$Self->{CacheTTL} = int( $Kernel::OM->Get('Kernel::Config')->Get('Process::CacheTTL') || 3600 );
# set lower if database is case sensitive
$Self->{Lower} = '';
if ( $Kernel::OM->Get('Kernel::System::DB')->GetDatabaseFunction('CaseSensitive') ) {
$Self->{Lower} = 'LOWER';
}
return $Self;
}
=head2 ActivityAdd()
add new Activity
returns the id of the created activity if success or undef otherwise
my $ID = $ActivityObject->ActivityAdd(
EntityID => 'A1' # mandatory, exportable unique identifier
Name => 'NameOfActivity', # mandatory
Config => $ConfigHashRef, # mandatory, activity configuration to be stored in YAML
# format
UserID => 123, # mandatory
);
Returns:
$ID = 567;
=cut
sub ActivityAdd {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Key (qw(EntityID Name Config UserID)) {
if ( !$Param{$Key} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Key!",
);
return;
}
}
# get database object
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
# check if EntityID already exists
return if !$DBObject->Prepare(
SQL => "
SELECT id
FROM pm_activity
WHERE $Self->{Lower}(entity_id) = $Self->{Lower}(?)",
Bind => [ \$Param{EntityID} ],
Limit => 1,
);
my $EntityExists;
while ( my @Data = $DBObject->FetchrowArray() ) {
$EntityExists = 1;
}
if ($EntityExists) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "The EntityID:$Param{EntityID} already exists for an activity!"
);
return;
}
# check config valid format
if ( ref $Param{Config} ne 'HASH' ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Config needs to be a valid Hash reference!",
);
return;
}
# dump config as string
my $Config = $Kernel::OM->Get('Kernel::System::YAML')->Dump( Data => $Param{Config} );
# Make sure the resulting string has the UTF-8 flag. YAML only sets it if
# part of the data already had it.
utf8::upgrade($Config);
# sql
return if !$DBObject->Do(
SQL => '
INSERT INTO pm_activity (entity_id, name, config, create_time, create_by, change_time,
change_by)
VALUES (?, ?, ?, current_timestamp, ?, current_timestamp, ?)',
Bind => [
\$Param{EntityID}, \$Param{Name}, \$Config, \$Param{UserID}, \$Param{UserID},
],
);
return if !$DBObject->Prepare(
SQL => 'SELECT id FROM pm_activity WHERE entity_id = ?',
Bind => [ \$Param{EntityID} ],
);
my $ID;
while ( my @Row = $DBObject->FetchrowArray() ) {
$ID = $Row[0];
}
# delete cache
$Kernel::OM->Get('Kernel::System::Cache')->CleanUp(
Type => 'ProcessManagement_Activity',
);
return if !$ID;
return $ID;
}
=head2 ActivityDelete()
delete an Activity
returns 1 if success or undef otherwise
my $Success = $ActivityObject->ActivityDelete(
ID => 123,
UserID => 123,
);
=cut
sub ActivityDelete {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Key (qw(ID UserID)) {
if ( !$Param{$Key} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Key!"
);
return;
}
}
# check if exists
my $Activity = $Self->ActivityGet(
ID => $Param{ID},
UserID => 1,
);
return if !IsHashRefWithData($Activity);
# delete activity
return if !$Kernel::OM->Get('Kernel::System::DB')->Do(
SQL => 'DELETE FROM pm_activity WHERE id = ?',
Bind => [ \$Param{ID} ],
);
# delete cache
$Kernel::OM->Get('Kernel::System::Cache')->CleanUp(
Type => 'ProcessManagement_Activity',
);
return 1;
}
=head2 ActivityGet()
get Activity attributes
my $Activity = $ActivityObject->ActivityGet(
ID => 123, # ID or EntityID is needed
EntityID => 'A1',
ActivityDialogNames => 1, # default 0, 1 || 0, if 0 returns an ActivityDialogs array
# with the activity dialog entity IDs, if 1 returns an
# ActivitiDialogs hash with the activity entity IDs as
# keys and ActivityDialog Names as values
UserID => 123, # mandatory
);
Returns:
$Activity = {
ID => 123,
EntityID => 'A1',
Name => 'some name',
Config => $ConfigHashRef,
ActiviyDialogs => ['AD1','AD2','AD3'],
CreateTime => '2012-07-04 15:08:00',
ChangeTime => '2012-07-04 15:08:00',
};
$Activity = {
ID => 123,
EntityID => 'P1',
Name => 'some name',
Config => $ConfigHashRef,
ActivityDialogs => {
'AD1' => 'ActivityDialog1',
'AD2' => 'ActivityDialog2',
'AD3' => 'ActivityDialog3',
};
CreateTime => '2012-07-04 15:08:00',
ChangeTime => '2012-07-04 15:08:00',
};
=cut
sub ActivityGet {
my ( $Self, %Param ) = @_;
# check needed stuff
if ( !$Param{ID} && !$Param{EntityID} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => 'Need ID or EntityID!'
);
return;
}
if ( !$Param{UserID} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => 'Need UserID!',
);
return;
}
my $ActivityDialogNames = 0;
if ( defined $Param{ActivityDialogNames} && $Param{ActivityDialogNames} == 1 ) {
$ActivityDialogNames = 1;
}
# check cache
my $CacheKey;
if ( $Param{ID} ) {
$CacheKey = 'ActivityGet::ID::' . $Param{ID} . '::ActivityDialogNames::'
. $ActivityDialogNames;
}
else {
$CacheKey = 'ActivityGet::EntityID::' . $Param{EntityID} . '::ActivityDialogNames::'
. $ActivityDialogNames;
}
# get cache object
my $CacheObject = $Kernel::OM->Get('Kernel::System::Cache');
my $Cache = $CacheObject->Get(
Type => 'ProcessManagement_Activity',
Key => $CacheKey,
);
return $Cache if $Cache;
# get database object
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
# sql
if ( $Param{ID} ) {
return if !$DBObject->Prepare(
SQL => '
SELECT id, entity_id, name, config, create_time, change_time
FROM pm_activity
WHERE id = ?',
Bind => [ \$Param{ID} ],
Limit => 1,
);
}
else {
return if !$DBObject->Prepare(
SQL => '
SELECT id, entity_id, name, config, create_time, change_time
FROM pm_activity
WHERE entity_id = ?',
Bind => [ \$Param{EntityID} ],
Limit => 1,
);
}
# get yaml object
my $YAMLObject = $Kernel::OM->Get('Kernel::System::YAML');
my %Data;
while ( my @Data = $DBObject->FetchrowArray() ) {
my $Config = $YAMLObject->Load( Data => $Data[3] );
%Data = (
ID => $Data[0],
EntityID => $Data[1],
Name => $Data[2],
Config => $Config,
CreateTime => $Data[4],
ChangeTime => $Data[5],
);
}
return if !$Data{ID};
# create the ActivityDialogsList
if ($ActivityDialogNames) {
my %ActivityDialogs;
if ( IsHashRefWithData( $Data{Config}->{ActivityDialog} ) ) {
# get activity dialog object
my $ActivityDialogObject = $Kernel::OM->Get('Kernel::System::ProcessManagement::DB::ActivityDialog');
my $ActivityDialogList = $ActivityDialogObject->ActivityDialogList(
UseEntities => 1,
UserID => 1,
);
for my $ActivityOrder ( sort { $a <=> $b } keys %{ $Data{Config}->{ActivityDialog} } ) {
$ActivityDialogs{ $Data{Config}->{ActivityDialog}->{$ActivityOrder} }
= $ActivityDialogList->{ $Data{Config}->{ActivityDialog}->{$ActivityOrder} };
}
}
$Data{ActivityDialogs} = \%ActivityDialogs;
}
else {
my @ActivityDialogList;
if ( IsHashRefWithData( $Data{Config}->{ActivityDialog} ) ) {
@ActivityDialogList = map { $Data{Config}->{ActivityDialog}->{$_} }
sort { $a <=> $b } keys %{ $Data{Config}->{ActivityDialog} };
}
$Data{ActivityDialogs} = \@ActivityDialogList;
}
# set cache
$CacheObject->Set(
Type => 'ProcessManagement_Activity',
Key => $CacheKey,
Value => \%Data,
TTL => $Self->{CacheTTL},
);
return \%Data;
}
=head2 ActivityUpdate()
update Activity attributes
returns 1 if success or undef otherwise
my $Success = $ActivityObject->ActivityUpdate(
ID => 123, # mandatory
EntityID => 'A1' # mandatory, exportable unique identifier
Name => 'NameOfProcess', # mandatory
Config => $ConfigHashRef, # mandatory, process configuration to be stored in YAML
# format
UserID => 123, # mandatory
);
=cut
sub ActivityUpdate {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Key (qw(ID EntityID Name Config UserID)) {
if ( !$Param{$Key} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Key!"
);
return;
}
}
# get database object
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
# check if EntityID already exists
return if !$DBObject->Prepare(
SQL => "
SELECT id FROM pm_activity
WHERE $Self->{Lower}(entity_id) = $Self->{Lower}(?)
AND id != ?",
Bind => [ \$Param{EntityID}, \$Param{ID} ],
LIMIT => 1,
);
my $EntityExists;
while ( my @Data = $DBObject->FetchrowArray() ) {
$EntityExists = 1;
}
if ($EntityExists) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "The EntityID:$Param{Name} already exists for a activity!",
);
return;
}
# check config valid format
if ( ref $Param{Config} ne 'HASH' ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Config needs to be a valid Hash reference!",
);
return;
}
# dump config as string
my $Config = $Kernel::OM->Get('Kernel::System::YAML')->Dump( Data => $Param{Config} );
# Make sure the resulting string has the UTF-8 flag. YAML only sets it if
# part of the data already had it.
utf8::upgrade($Config);
# check if need to update db
return if !$DBObject->Prepare(
SQL => '
SELECT entity_id, name, config
FROM pm_activity
WHERE id = ?',
Bind => [ \$Param{ID} ],
Limit => 1,
);
my $CurrentEntityID;
my $CurrentName;
my $CurrentConfig;
while ( my @Data = $DBObject->FetchrowArray() ) {
$CurrentEntityID = $Data[0];
$CurrentName = $Data[1];
$CurrentConfig = $Data[2];
}
if ($CurrentEntityID) {
return 1 if $CurrentEntityID eq $Param{EntityID}
&& $CurrentName eq $Param{Name}
&& $CurrentConfig eq $Config;
}
# sql
return if !$DBObject->Do(
SQL => '
UPDATE pm_activity
SET entity_id = ?, name = ?, config = ?, change_time = current_timestamp, change_by = ?
WHERE id = ?',
Bind => [
\$Param{EntityID}, \$Param{Name}, \$Config, \$Param{UserID},
\$Param{ID},
],
);
# delete cache
$Kernel::OM->Get('Kernel::System::Cache')->CleanUp(
Type => 'ProcessManagement_Activity',
);
return 1;
}
=head2 ActivityList()
get an Activity list
my $List = $ActivityObject->ActivityList(
UseEntities => 0, # default 0, 1 || 0. if 0 the return hash keys are
# the activity IDs otherwise keys are the
# activity entity IDs
UserID => 1,
);
Returns:
$List = {
1 => 'Activity1',
}
or
$List = {
'A1' => 'Activity1',
}
=cut
sub ActivityList {
my ( $Self, %Param ) = @_;
# check needed
if ( !$Param{UserID} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need UserID!"
);
return;
}
# get cache object
my $CacheObject = $Kernel::OM->Get('Kernel::System::Cache');
# check cache
my $UseEntities = 0;
if ( defined $Param{UseEntities} && $Param{UseEntities} ) {
$UseEntities = 1;
}
my $CacheKey = 'ActivityList::UseEntities::' . $UseEntities;
my $Cache = $CacheObject->Get(
Type => 'ProcessManagement_Activity',
Key => $CacheKey,
);
return $Cache if ref $Cache;
# get database object
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
return if !$DBObject->Prepare(
SQL => '
SELECT id, entity_id, name
FROM pm_activity',
);
my %Data;
while ( my @Row = $DBObject->FetchrowArray() ) {
if ( !$UseEntities ) {
$Data{ $Row[0] } = $Row[2];
}
else {
$Data{ $Row[1] } = $Row[2];
}
}
# set cache
$CacheObject->Set(
Type => 'ProcessManagement_Activity',
Key => $CacheKey,
Value => \%Data,
TTL => $Self->{CacheTTL},
);
return \%Data;
}
=head2 ActivityListGet()
get an Activity list with all activity details
my $List = $ActivityObject->ActivityListGet(
UserID => 1,
);
Returns:
$List = [
{
ID => 123,
EntityID => 'A1',
Name => 'some name',
Config => $ConfigHashRef,
ActiviyDialogs => ['AD1','AD2','AD3'],
CreateTime => '2012-07-04 15:08:00',
ChangeTime => '2012-07-04 15:08:00',
}
{
ID => 456,
EntityID => 'A2',
Name => 'some name',
Config => $ConfigHashRef,
ActiviyDialogs => ['AD3','AD4','AD5'],
CreateTime => '2012-07-04 15:09:00',
ChangeTime => '2012-07-04 15:09:00',
}
];
=cut
sub ActivityListGet {
my ( $Self, %Param ) = @_;
# check needed stuff
if ( !$Param{UserID} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => 'Need UserID!',
);
return;
}
# get cache object
my $CacheObject = $Kernel::OM->Get('Kernel::System::Cache');
# check cache
my $CacheKey = 'ActivityListGet';
my $Cache = $CacheObject->Get(
Type => 'ProcessManagement_Activity',
Key => $CacheKey,
);
return $Cache if $Cache;
# get database object
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
# sql
return if !$DBObject->Prepare(
SQL => '
SELECT id, entity_id
FROM pm_activity
ORDER BY id',
);
my @ActivityIDs;
while ( my @Row = $DBObject->FetchrowArray() ) {
push @ActivityIDs, $Row[0];
}
my @Data;
for my $ItemID (@ActivityIDs) {
my $ActivityData = $Self->ActivityGet(
ID => $ItemID,
UserID => 1,
);
push @Data, $ActivityData;
}
# set cache
$CacheObject->Set(
Type => 'ProcessManagement_Activity',
Key => $CacheKey,
Value => \@Data,
TTL => $Self->{CacheTTL},
);
return \@Data;
}
=head2 ActivitySearch()
search activities by process name
my $ActivityEntityIDs = $ActivityObject->ActivitySearch(
ActivityName => 'SomeText', # e. g. "SomeText*", "Some*ext" or ['*SomeTest1*', '*SomeTest2*']
);
Returns:
$ActivityEntityIDs = [ 'Activity-e11e2e9aa83344a235279d4f6babc6ec', 'Activity-f8194a25ab0ccddefeb4240c281c1f56' ];
=cut
sub ActivitySearch {
my ( $Self, %Param ) = @_;
# check needed stuff
if ( !$Param{ActivityName} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => 'Need ActivityName!',
);
return;
}
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
my $SQL = 'SELECT DISTINCT entity_id
FROM pm_activity ';
# if it's no ref, put it to array ref
if ( ref $Param{ActivityName} eq '' ) {
$Param{ActivityName} = [ $Param{ActivityName} ];
}
if ( IsArrayRefWithData( $Param{ActivityName} ) ) {
$SQL .= ' WHERE' if IsArrayRefWithData( $Param{ActivityName} );
}
my @QuotedSearch;
my $SQLOR = 0;
VALUE:
for my $Value ( @{ $Param{ActivityName} } ) {
next VALUE if !defined $Value || !length $Value;
$Value = '%' . $DBObject->Quote( $Value, 'Like' ) . '%';
$Value =~ s/\*/%/g;
$Value =~ s/%%/%/gi;
if ($SQLOR) {
$SQL .= ' OR';
}
$SQL .= ' name LIKE ? ';
push @QuotedSearch, $Value;
$SQLOR = 1;
}
if ( IsArrayRefWithData( $Param{ActivityName} ) ) {
$SQL .= $DBObject->GetDatabaseFunction('LikeEscapeString');
}
$SQL .= ' ORDER BY entity_id';
return if !$DBObject->Prepare(
SQL => $SQL,
Bind => [ \(@QuotedSearch) ]
);
my @Data;
while ( my @Row = $DBObject->FetchrowArray() ) {
push @Data, $Row[0];
}
return \@Data;
}
1;
=head1 TERMS AND CONDITIONS
This software is part of the OTRS project (L).
This software comes with ABSOLUTELY NO WARRANTY. For details, see
the enclosed file COPYING for license information (GPL). If you
did not receive this file, see L.
=cut