NAME
Kernel::System::Ticket::Article – functions to manage ticket articles
DESCRIPTION
Since OTRS 6, article data is split in a neutral part for all articles (in the article
database table), and back end specific data in custom tables (such as article_data_mime
for the MIME
based back ends).
This class only manages back end neutral article data, like listing articles with "ArticleList()" or manipulating article metadata like "ArticleFlagSet()".
For all operations involving back end specific article data (like ArticleCreate
and ArticleGet
), please call "BackendForArticle()" or "BackendForChannel()" to get to the correct article back end. See "ArticleList()" for an example of looping over all article data of a ticket.
See Kernel::System::Ticket::Article::Backend::Base for the definition of the basic interface of all article back ends.
PUBLIC INTERFACE
new()
Don't use the constructor directly, use the ObjectManager instead:
my $ArticleObject = $Kernel::OM->Get('Kernel::System::Ticket::Article');
BackendForArticle()
Returns the correct back end for a given article, or the Invalid back end, so that you can always expect a back end object instance that can be used for chain-calling.
my $ArticleBackendObject = $ArticleObject->BackendForArticle( TicketID => 42, ArticleID => 123 );
Alternatively, you can pass in a hash with base article data as returned by "ArticleList()", this will avoid the lookup for the CommunicationChannelID
of the article:
my $ArticleBackendObject = $ArticleObject->BackendForArticle( %BaseArticle );
See Kernel::System::Ticket::Article::Backend::Base for the definition of the basic interface of all article back ends.
BackendForChannel()
Returns the correct back end for a given communication channel, or the Invalid
back end, so that you can always expect a back end object instance that can be used for chain-calling.
my $ArticleBackendObject = $ArticleObject->BackendForChannel( ChannelName => 'Email' );
See Kernel::System::Ticket::Article::Backend::Base for the definition of the basic interface of all article back ends.
ArticleList()
Returns an filtered array of base article data for a ticket.
my @Articles = $ArticleObject->ArticleList(
TicketID => 123,
# Optional filters, these can be combined:
ArticleID => 234, # optional, limit to one article (if present on a ticket)
CommunicationChannel => 'Email', # optional, to limit to a certain CommunicationChannel
CommunicationChannelID => 2, # optional, to limit to a certain CommunicationChannelID
SenderType => 'customer', # optional, to limit to a certain article SenderType
SenderTypeID => 2, # optional, to limit to a certain article SenderTypeID
IsVisibleForCustomer => 0, # optional, to limit to a certain visibility
# After filtering, you can also limit to first or last found article only:
OnlyFirst => 0, # optional, only return first match
OnlyLast => 0, # optional, only return last match
);
Returns a list with base article data (no back end related data included):
(
{
ArticleID => 1,
TicketID => 2,
ArticleNumber => 1, # sequential number of article in the ticket
CommunicationChannelID => 1,
SenderTypeID => 1,
IsVisibleForCustomer => 0,
CreateBy => 1,
CreateTime => '2017-03-01 00:00:00',
ChangeBy => 1,
ChangeTime => '2017-03-01 00:00:00',
},
{ ... }
)
Please note that you need to use ArticleGet() via the article backend objects to access the full backend-specific article data hash for each article.
for my $MetaArticle (@Articles) {
my %Article = $ArticleObject->BackendForArticle( %{$MetaArticle} )->ArticleGet( %{$MetaArticle} );
}
TicketIDLookup()
Get a ticket ID for supplied article ID.
my $TicketID = $ArticleObject->TicketIDLookup(
ArticleID => 123, # required
);
Returns ID of a ticket that article belongs to:
$TicketID = 123;
NOTE: Usage of this lookup function is strongly discouraged, since its result is not cached. Where possible, use ArticleList()
instead.
ArticleFlagsSet()
Set article flag for multiple articles.
my $Success = $ArticleObject->ArticleFlagsSet(
TicketID => 123,
ArticleIDs => [123, 123],
Key => 'Seen',
Value => 1,
UserID => 123,
);
Events: ArticleFlagsSet
ArticleFlagSet()
Set article flags.
my $Success = $ArticleObject->ArticleFlagSet(
TicketID => 123,
ArticleID => 123,
Key => 'Seen',
Value => 1,
UserID => 123,
);
Events: ArticleFlagSet
ArticleFlagDelete()
Delete an article flag.
my $Success = $ArticleObject->ArticleFlagDelete(
TicketID => 123,
ArticleID => 123,
Key => 'seen',
UserID => 123,
);
my $Success = $ArticleObject->ArticleFlagDelete(
TicketID => 123,
ArticleID => 123,
Key => 'seen',
AllUsers => 1, # delete for all users
);
Events: ArticleFlagDelete
ArticleFlagGet()
Get article flags.
my %Flags = $ArticleObject->ArticleFlagGet(
ArticleID => 123,
UserID => 123,
);
ArticleFlagsOfTicketGet()
Get all article flags of a ticket.
my %Flags = $ArticleObject->ArticleFlagsOfTicketGet(
TicketID => 123,
UserID => 123,
);
returns (
123 => { # ArticleID
'Seen' => 1,
'Other' => 'something',
},
)
ArticleCustomerFlagSet()
Set customer article flags.
my $Success = $ArticleObject->ArticleCustomerFlagSet(
TicketID => 123,
ArticleID => 123,
Key => 'Seen',
Value => 1,
Login => 'jdoe,
);
Events: ArticleCustomerFlagSet
ArticleCustomerFlagDelete()
Delete customer article flag.
my $Success = $ArticleObject->ArticleCustomerFlagDelete(
TicketID => 123,
ArticleID => 123,
Key => 'seen',
Login => 'jdoe',
);
my $Success = $ArticleObject->ArticleCustomerFlagDelete(
TicketID => 123,
ArticleID => 123,
Key => 'seen',
AllCustomerUsers => 1, # delete for all customer users
);
Events: ArticleCustomerFlagDelete
ArticleCustomerFlagGet()
Get article flags.
my %Flags = $ArticleObject->ArticleCustomerFlagGet(
ArticleID => 123,
Login => 'jdoe',
);
ArticleCustomerFlagsOfTicketGet()
Get all article flags of a ticket.
my %Flags = $ArticleObject->ArticleCustomerFlagsOfTicketGet(
TicketID => 123,
Login => 'jdoe',
);
returns (
'123' => { # ArticleID
'Seen' => 1,
'Other' => 'something',
},
)
ArticleAccountedTimeGet()
Returns the accounted time of a article.
my $AccountedTime = $ArticleObject->ArticleAccountedTimeGet(
ArticleID => $ArticleID,
);
ArticleAccountedTimeDelete()
Delete accounted time of an article.
my $Success = $ArticleObject->ArticleAccountedTimeDelete(
ArticleID => $ArticleID,
);
ArticleSenderTypeList()
List all article sender types.
my %ArticleSenderTypeList = $ArticleObject->ArticleSenderTypeList();
Returns:
(
1 => 'agent',
2 => 'customer',
3 => 'system',
)
ArticleSenderTypeLookup()
Lookup an article sender type id or name.
my $SenderTypeID = $ArticleObject->ArticleSenderTypeLookup(
SenderType => 'customer', # customer|system|agent
);
my $SenderType = $ArticleObject->ArticleSenderTypeLookup(
SenderTypeID => 1,
);
ArticleSearchIndexRebuildFlagSet()
Set the article flags to indicate if the article search index needs to be rebuilt.
my $Success = $ArticleObject->ArticleSearchIndexRebuildFlagSet(
ArticleIDs => [ 123, 234, 345 ] # (Either 'ArticleIDs' or 'All' must be provided) The ArticleIDs to be updated.
All => 1 # (Either 'ArticleIDs' or 'All' must be provided) Set all articles to $Value. Default: 0,
Value => 1, # 0/1 default 0
);
ArticleSearchIndexRebuildFlagList()
Get a list of ArticleIDs and TicketIDs for a given flag (either needs rebuild or not)
my %ArticleTicketIDs = $ArticleObject->ArticleSearchIndexRebuildFlagList(
Value => 1, # (optional) 0/1 default 0
Limit => 10000, # (optional) default: 20000
);
Returns:
%ArticleIDs = (
1 => 2, # ArticleID => TicketID
3 => 4,
5 => 6,
...
);
ArticleSearchIndexStatus()
gets an article indexing status hash.
my %Status = $ArticleObject->ArticleSearchIndexStatus();
Returns:
%Status = (
ArticlesTotal => 443,
ArticlesIndexed => 420,
ArticlesNotIndexed => 23,
);
ArticleSearchIndexBuild()
Rebuilds the current article search index table content. Existing article entries will be replaced.
my $Success = $ArticleObject->ArticleSearchIndexBuild(
TicketID => 123,
ArticleID => 123,
UserID => 1,
);
Returns:
True if indexing process was successfully finished, False if not.
ArticleSearchIndexDelete()
Deletes entries from the article search index table base on supplied ArticleID
or TicketID
.
my $Success = $ArticleObject->ArticleSearchIndexDelete(
ArticleID => 123, # required, deletes search index for single article
# or
TicketID => 123, # required, deletes search index for all ticket articles
UserID => 1, # required
);
Returns:
True if delete process was successfully finished, False if not.
ArticleSearchIndexSQLJoinNeeded()
Checks the given search parameters for used article backend fields.
my $Needed = $ArticleObject->ArticleSearchIndexSQLJoinNeeded(
SearchParams => {
...
ConditionInline => 1,
ContentSearchPrefix => '*',
ContentSearchSuffix => '*',
MIMEBase_From => '%spam@example.com%',
MIMEBase_To => '%service@example.com%',
MIMEBase_Cc => '%client@example.com%',
MIMEBase_Subject => '%VIRUS 32%',
MIMEBase_Body => '%VIRUS 32%',
MIMEBase_AttachmentName => '%anyfile.txt%',
Chat_ChatterName => '%Some Chatter Name%',
Chat_MessageText => '%Some Message Text%'
...
},
);
Returns:
True if article search index usage is needed, False if not.
ArticleSearchIndexSQLJoin()
Generates SQL string extensions, including the needed table joins for the article index search.
my $SQLExtenion = $ArticleObject->ArticleSearchIndexSQLJoin(
SearchParams => {
...
ConditionInline => 1,
ContentSearchPrefix => '*',
ContentSearchSuffix => '*',
MIMEBase_From => '%spam@example.com%',
MIMEBase_To => '%service@example.com%',
MIMEBase_Cc => '%client@example.com%',
MIMEBase_Subject => '%VIRUS 32%',
MIMEBase_Body => '%VIRUS 32%',
MIMEBase_AttachmentName => '%anyfile.txt%',
Chat_ChatterName => '%Some Chatter Name%',
Chat_MessageText => '%Some Message Text%'
...
},
);
Returns:
$SQLExtension = 'LEFT JOIN article_search_index ArticleFulltext ON art.id = ArticleFulltext.article_id ';
ArticleSearchIndexWhereCondition()
Generates SQL query conditions for the used article fields, that may be used in the WHERE clauses of main SQL queries to the database.
my $SQLExtenion = $ArticleObject->ArticleSearchIndexWhereCondition(
SearchParams => {
...
ConditionInline => 1,
ContentSearchPrefix => '*',
ContentSearchSuffix => '*',
MIMEBase_From => '%spam@example.com%',
MIMEBase_To => '%service@example.com%',
MIMEBase_Cc => '%client@example.com%',
MIMEBase_Subject => '%VIRUS 32%',
MIMEBase_Body => '%VIRUS 32%',
MIMEBase_AttachmentName => '%anyfile.txt%',
Chat_ChatterName => '%Some Chatter Name%',
Chat_MessageText => '%Some Message Text%'
...
},
);
Returns:
$SQLConditions = " AND (MIMEBase_From.article_value LIKE '%spam@example.com%') ";
SearchStringStopWordsFind()
Find stop words within given search string.
my $StopWords = $ArticleObject->SearchStringStopWordsFind(
SearchStrings => {
'Fulltext' => '(this AND is) OR test',
'MIMEBase_From' => 'myself',
},
);
Returns Hashref with found stop words.
SearchStringStopWordsUsageWarningActive()
Checks if warnings for stop words in search strings are active or not.
my $WarningActive = $ArticleObject->SearchStringStopWordsUsageWarningActive();
ArticleSearchableFieldsList()
Get list of searchable fields across all article backends.
my %SearchableFields = $ArticleObject->ArticleSearchableFieldsList();
Returns:
%SearchableFields = (
'MIMEBase_Body' => {
Filterable => 1,
Key => 'MIMEBase_Body',
Label => 'Article Note or Email Message Body',
Type => 'Text',
},
'MIMEBase_Subject' => {
Filterable => 1,
Key => 'MIMEBase_Subject',
Label => 'Article Note or Email Message Subject',
Type => 'Text',
},
...
);
PRIVATE FUNCTIONS
_MetaArticleList()
Returns an array-hash with the meta articles of the current ticket.
my @MetaArticles = $ArticleObject->_MetaArticleList(
TicketID => 123,
);
Returns:
(
{
ArticleID => 1,
TicketID => 2,
ArticleNumber => 1, # sequential number of article in the ticket
CommunicationChannelID => 1,
SenderTypeID => 1,
IsVisibleForCustomer => 0,
CreateBy => 1,
CreateTime => '2017-03-01 00:00:00',
ChangeBy => 1,
ChangeTime => '2017-03-01 00:00:00',
},
{ ... },
)
_ArticleCacheClear()
Removes all article caches related to specified ticket.
my $Success = $ArticleObject->_ArticleCacheClear(
TicketID => 123,
);
_BulkInsert()
Add batch entries to the DB into a given table.
my $Success = $ArticleObject->_BulkInsert(
Table => 'table_name', # (required) Table name
Columns => [ # (required) Array of column names
'column_name',
...
],
Data => [ # (required) AoA with data
[
'record 1',
'record 2',
],
[
...
],
...
],
);