#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
sub Table { 'Tickets'}
use RT::CustomFields;
-use DBIx::SearchBuilder::Unique;
# Configuration Tables:
QueueCc => [ 'WATCHERFIELD' => 'Cc' => 'Queue', ], #loc_left_pair
QueueAdminCc => [ 'WATCHERFIELD' => 'AdminCc' => 'Queue', ], #loc_left_pair
QueueWatcher => [ 'WATCHERFIELD' => undef => 'Queue', ], #loc_left_pair
- CustomFieldValue => [ 'CUSTOMFIELD', ], #loc_left_pair
- CustomField => [ 'CUSTOMFIELD', ], #loc_left_pair
- CF => [ 'CUSTOMFIELD', ], #loc_left_pair
+ CustomFieldValue => [ 'CUSTOMFIELD' => 'Ticket' ], #loc_left_pair
+ CustomField => [ 'CUSTOMFIELD' => 'Ticket' ], #loc_left_pair
+ CF => [ 'CUSTOMFIELD' => 'Ticket' ], #loc_left_pair
Updated => [ 'TRANSDATE', ], #loc_left_pair
RequestorGroup => [ 'MEMBERSHIPFIELD' => 'Requestor', ], #loc_left_pair
CCGroup => [ 'MEMBERSHIPFIELD' => 'Cc', ], #loc_left_pair
WillResolve => [ 'DATE' => 'WillResolve', ], #loc_left_pair
);
+# Lower Case version of FIELDS, for case insensitivity
+our %LOWER_CASE_FIELDS = map { ( lc($_) => $_ ) } (keys %FIELD_METADATA);
+
our %SEARCHABLE_SUBFIELDS = (
User => [qw(
EmailAddress Name RealName Nickname Organization Address1 Address2
my $class = "RT::" . $meta->[1];
my $o = $class->new( $sb->CurrentUser );
$o->Load($value);
- $value = $o->Id;
+ $value = $o->Id || 0;
+ } elsif ( $field eq "Type" ) {
+ $value = lc $value if $value =~ /^(ticket|approval|reminder)$/i;
+ } elsif ($field eq "Status") {
+ $value = lc $value;
}
$sb->_SQLLimit(
FIELD => $field,
my $is_null = 0;
$is_null = 1 if !$value || $value =~ /^null$/io;
- unless ($is_null) {
- $value = RT::URI->new( $sb->CurrentUser )->CanonicalizeURI( $value );
- }
-
my $direction = $meta->[1] || '';
my ($matchfield, $linkfield) = ('', '');
if ( $direction eq 'To' ) {
my $is_local = 1;
if ( $is_null ) {
- $op = ($op =~ /^(=|IS)$/)? 'IS': 'IS NOT';
+ $op = ($op =~ /^(=|IS)$/i)? 'IS': 'IS NOT';
}
elsif ( $value =~ /\D/ ) {
+ $value = RT::URI->new( $sb->CurrentUser )->CanonicalizeURI( $value );
$is_local = 0;
}
$matchfield = "Local$matchfield" if $is_local;
die "Invalid watcher subfield: '$rest{SUBKEY}'";
}
+ # if it's equality op and search by Email or Name then we can preload user
+ # we do it to help some DBs better estimate number of rows and get better plans
+ if ( $op =~ /^!?=$/ && (!$rest{'SUBKEY'} || $rest{'SUBKEY'} eq 'Name' || $rest{'SUBKEY'} eq 'EmailAddress') ) {
+ my $o = RT::User->new( $self->CurrentUser );
+ my $method =
+ !$rest{'SUBKEY'}
+ ? $field eq 'Owner'? 'Load' : 'LoadByEmail'
+ : $rest{'SUBKEY'} eq 'EmailAddress' ? 'LoadByEmail': 'Load';
+ $o->$method( $value );
+ $rest{'SUBKEY'} = 'id';
+ $value = $o->id || 0;
+ }
+
# Owner was ENUM field, so "Owner = 'xxx'" allowed user to
# search by id and Name at the same time, this is workaround
# to preserve backward compatibility
if ( $field eq 'Owner' ) {
- if ( $op =~ /^!?=$/ && (!$rest{'SUBKEY'} || $rest{'SUBKEY'} eq 'Name' || $rest{'SUBKEY'} eq 'EmailAddress') ) {
- my $o = RT::User->new( $self->CurrentUser );
- my $method = ($rest{'SUBKEY'}||'') eq 'EmailAddress' ? 'LoadByEmail': 'Load';
- $o->$method( $value );
- $self->_SQLLimit(
- FIELD => 'Owner',
- OPERATOR => $op,
- VALUE => $o->id,
- %rest,
- );
- return;
- }
if ( ($rest{'SUBKEY'}||'') eq 'id' ) {
$self->_SQLLimit(
FIELD => 'Owner',
}
$rest{SUBKEY} ||= 'EmailAddress';
- my $groups = $self->_RoleGroupsJoin( Type => $type, Class => $class, New => !$type );
+ my ($groups, $group_members, $users);
+ if ( $rest{'BUNDLE'} ) {
+ ($groups, $group_members, $users) = @{ $rest{'BUNDLE'} };
+ } else {
+ $groups = $self->_RoleGroupsJoin( Type => $type, Class => $class, New => !$type );
+ }
$self->_OpenParen;
- if ( $op =~ /^IS(?: NOT)?$/ ) {
+ if ( $op =~ /^IS(?: NOT)?$/i ) {
# is [not] empty case
- my $group_members = $self->_GroupMembersJoin( GroupsAlias => $groups );
+ $group_members ||= $self->_GroupMembersJoin( GroupsAlias => $groups );
# to avoid joining the table Users into the query, we just join GM
# and make sure we don't match records where group is member of itself
$self->SUPER::Limit(
$users_obj->RowsPerPage(2);
my @users = @{ $users_obj->ItemsArrayRef };
- my $group_members = $self->_GroupMembersJoin( GroupsAlias => $groups );
+ $group_members ||= $self->_GroupMembersJoin( GroupsAlias => $groups );
if ( @users <= 1 ) {
my $uid = 0;
$uid = $users[0]->id if @users;
VALUE => "$group_members.MemberId",
QUOTEVALUE => 0,
);
- my $users = $self->Join(
+ $users ||= $self->Join(
TYPE => 'LEFT',
ALIAS1 => $group_members,
FIELD1 => 'MemberId',
} else {
# positive condition case
- my $group_members = $self->_GroupMembersJoin(
+ $group_members ||= $self->_GroupMembersJoin(
GroupsAlias => $groups, New => 1, Left => 0
);
- my $users = $self->Join(
+ $users ||= $self->Join(
TYPE => 'LEFT',
ALIAS1 => $group_members,
FIELD1 => 'MemberId',
);
}
$self->_CloseParen;
+ return ($groups, $group_members, $users);
}
sub _RoleGroupsJoin {
Try and turn a CF descriptor into (cfid, cfname) object pair.
+Takes an optional second parameter of the CF LookupType, defaults to Ticket CFs.
+
=cut
sub _CustomFieldDecipher {
- my ($self, $string) = @_;
+ my ($self, $string, $lookuptype) = @_;
+ $lookuptype ||= $self->_SingularClass->CustomFieldLookupType;
- my ($queue, $field, $column) = ($string =~ /^(?:(.+?)\.)?{(.+)}(?:\.(Content|LargeContent))?$/);
+ my ($object, $field, $column) = ($string =~ /^(?:(.+?)\.)?\{(.+)\}(?:\.(Content|LargeContent))?$/);
$field ||= ($string =~ /^{(.*?)}$/)[0] || $string;
- my $cf;
- if ( $queue ) {
- my $q = RT::Queue->new( $self->CurrentUser );
- $q->Load( $queue );
+ my ($cf, $applied_to);
- if ( $q->id ) {
- # $queue = $q->Name; # should we normalize the queue?
- $cf = $q->CustomField( $field );
+ if ( $object ) {
+ my $record_class = RT::CustomField->RecordClassFromLookupType($lookuptype);
+ $applied_to = $record_class->new( $self->CurrentUser );
+ $applied_to->Load( $object );
+
+ if ( $applied_to->id ) {
+ RT->Logger->debug("Limiting to CFs identified by '$field' applied to $record_class #@{[$applied_to->id]} (loaded via '$object')");
}
else {
- $RT::Logger->warning("Queue '$queue' doesn't exist, parsed from '$string'");
- $queue = 0;
+ RT->Logger->warning("$record_class '$object' doesn't exist, parsed from '$string'");
+ $object = 0;
+ undef $applied_to;
}
}
- elsif ( $field =~ /\D/ ) {
- $queue = '';
+
+ if ( $field =~ /\D/ ) {
+ $object ||= '';
my $cfs = RT::CustomFields->new( $self->CurrentUser );
- $cfs->Limit( FIELD => 'Name', VALUE => $field );
- $cfs->LimitToLookupType('RT::Queue-RT::Ticket');
+ $cfs->Limit( FIELD => 'Name', VALUE => $field, ($applied_to ? (CASESENSITIVE => 0) : ()) );
+ $cfs->LimitToLookupType($lookuptype);
+
+ if ($applied_to) {
+ $cfs->SetContextObject($applied_to);
+ $cfs->LimitToObjectId($applied_to->id);
+ }
# if there is more then one field the current user can
# see with the same name then we shouldn't return cf object
else {
$cf = RT::CustomField->new( $self->CurrentUser );
$cf->Load( $field );
+ $cf->SetContextObject($applied_to)
+ if $cf->id and $applied_to;
}
- return ($queue, $field, $cf, $column);
+ return ($object, $field, $cf, $column);
}
=head2 _CustomFieldJoin
=cut
+our %JOIN_ALIAS_FOR_LOOKUP_TYPE = (
+ RT::Ticket->CustomFieldLookupType => sub { "main" },
+);
+
sub _CustomFieldJoin {
- my ($self, $cfkey, $cfid, $field) = @_;
+ my ($self, $cfkey, $cfid, $field, $type) = @_;
+ $type ||= RT::Ticket->CustomFieldLookupType;
+
# Perform one Join per CustomField
if ( $self->{_sql_object_cfv_alias}{$cfkey} ||
$self->{_sql_cf_alias}{$cfkey} )
$self->{_sql_cf_alias}{$cfkey} );
}
- my ($TicketCFs, $CFs);
+ my $ObjectAlias = $JOIN_ALIAS_FOR_LOOKUP_TYPE{$type}
+ ? $JOIN_ALIAS_FOR_LOOKUP_TYPE{$type}->($self)
+ : die "We don't know how to join on $type";
+
+ my ($ObjectCFs, $CFs);
if ( $cfid ) {
- $TicketCFs = $self->{_sql_object_cfv_alias}{$cfkey} = $self->Join(
+ $ObjectCFs = $self->{_sql_object_cfv_alias}{$cfkey} = $self->Join(
TYPE => 'LEFT',
- ALIAS1 => 'main',
+ ALIAS1 => $ObjectAlias,
FIELD1 => 'id',
TABLE2 => 'ObjectCustomFieldValues',
FIELD2 => 'ObjectId',
);
$self->SUPER::Limit(
- LEFTJOIN => $TicketCFs,
+ LEFTJOIN => $ObjectCFs,
FIELD => 'CustomField',
VALUE => $cfid,
ENTRYAGGREGATOR => 'AND'
LEFTJOIN => $CFs,
ENTRYAGGREGATOR => 'AND',
FIELD => 'LookupType',
- VALUE => 'RT::Queue-RT::Ticket',
+ VALUE => $type,
);
$self->SUPER::Limit(
LEFTJOIN => $CFs,
VALUE => $field,
);
- $TicketCFs = $self->{_sql_object_cfv_alias}{$cfkey} = $self->Join(
+ $ObjectCFs = $self->{_sql_object_cfv_alias}{$cfkey} = $self->Join(
TYPE => 'LEFT',
ALIAS1 => $CFs,
FIELD1 => 'id',
FIELD2 => 'CustomField',
);
$self->SUPER::Limit(
- LEFTJOIN => $TicketCFs,
+ LEFTJOIN => $ObjectCFs,
FIELD => 'ObjectId',
- VALUE => 'main.id',
+ VALUE => "$ObjectAlias.id",
QUOTEVALUE => 0,
ENTRYAGGREGATOR => 'AND',
);
}
+
$self->SUPER::Limit(
- LEFTJOIN => $TicketCFs,
+ LEFTJOIN => $ObjectCFs,
FIELD => 'ObjectType',
- VALUE => 'RT::Ticket',
+ VALUE => RT::CustomField->ObjectTypeFromLookupType($type),
ENTRYAGGREGATOR => 'AND'
);
$self->SUPER::Limit(
- LEFTJOIN => $TicketCFs,
+ LEFTJOIN => $ObjectCFs,
FIELD => 'Disabled',
OPERATOR => '=',
VALUE => '0',
ENTRYAGGREGATOR => 'AND'
);
- return ($TicketCFs, $CFs);
+ return ($ObjectCFs, $CFs);
}
=head2 _CustomFieldLimit
sub _CustomFieldLimit {
my ( $self, $_field, $op, $value, %rest ) = @_;
+ my $meta = $FIELD_METADATA{ $_field };
+ my $class = $meta->[1] || 'Ticket';
+ my $type = "RT::$class"->CustomFieldLookupType;
+
my $field = $rest{'SUBKEY'} || die "No field specified";
# For our sanity, we can only limit on one queue at a time
- my ($queue, $cfid, $cf, $column);
- ($queue, $field, $cf, $column) = $self->_CustomFieldDecipher( $field );
+ my ($object, $cfid, $cf, $column);
+ ($object, $field, $cf, $column) = $self->_CustomFieldDecipher( $field, $type );
$cfid = $cf ? $cf->id : 0 ;
# If we're trying to find custom fields that don't match something, we
}
if ( $cf && $cf->Type eq 'IPAddressRange' ) {
-
- if ( $value =~ /^\s*$RE{net}{CIDR}{IPv4}{-keep}\s*$/o ) {
-
- # convert incomplete 192.168/24 to 192.168.0.0/24 format
- $value =
- join( '.', map $_ || 0, ( split /\./, $1 )[ 0 .. 3 ] ) . "/$2"
- || $value;
- }
-
my ( $start_ip, $end_ip ) =
RT::ObjectCustomFieldValue->ParseIPRange($value);
if ( $start_ip && $end_ip ) {
}
}
+ if ( $cf && $cf->Type =~ /^Date(?:Time)?$/ ) {
+ my $date = RT::Date->new( $self->CurrentUser );
+ $date->Set( Format => 'unknown', Value => $value );
+ if ( $date->Unix ) {
+
+ if (
+ $cf->Type eq 'Date'
+ || $value =~ /^\s*(?:today|tomorrow|yesterday)\s*$/i
+ || ( $value !~ /midnight|\d+:\d+:\d+/i
+ && $date->Time( Timezone => 'user' ) eq '00:00:00' )
+ )
+ {
+ $value = $date->Date( Timezone => 'user' );
+ }
+ else {
+ $value = $date->DateTime;
+ }
+ }
+ else {
+ $RT::Logger->warn("$value is not a valid date string");
+ }
+ }
+
my $single_value = !$cf || !$cfid || $cf->SingleValue;
- my $cfkey = $cfid ? $cfid : "$queue.$field";
+ my $cfkey = $cfid ? $cfid : "$type-$object.$field";
if ( $null_op && !$column ) {
# IS[ NOT] NULL without column is the same as has[ no] any CF value,
# we can reuse our default joins for this operation
# with column specified we have different situation
- my ($TicketCFs, $CFs) = $self->_CustomFieldJoin( $cfkey, $cfid, $field );
+ my ($ObjectCFs, $CFs) = $self->_CustomFieldJoin( $cfkey, $cfid, $field, $type );
$self->_OpenParen;
$self->_SQLLimit(
- ALIAS => $TicketCFs,
+ ALIAS => $ObjectCFs,
FIELD => 'id',
OPERATOR => $op,
VALUE => $value,
$self->_OpenParen;
if ( $op !~ /NOT|!=|<>/i ) { # positive equation
$self->_CustomFieldLimit(
- 'CF', '<=', $end_ip, %rest,
+ $_field, '<=', $end_ip, %rest,
SUBKEY => $rest{'SUBKEY'}. '.Content',
);
$self->_CustomFieldLimit(
- 'CF', '>=', $start_ip, %rest,
+ $_field, '>=', $start_ip, %rest,
SUBKEY => $rest{'SUBKEY'}. '.LargeContent',
ENTRYAGGREGATOR => 'AND',
);
# estimations and scan less rows
# have to disable this tweak because of ipv6
# $self->_CustomFieldLimit(
-# $field, '>=', '000.000.000.000', %rest,
+# $_field, '>=', '000.000.000.000', %rest,
# SUBKEY => $rest{'SUBKEY'}. '.Content',
# ENTRYAGGREGATOR => 'AND',
# );
# $self->_CustomFieldLimit(
-# $field, '<=', '255.255.255.255', %rest,
+# $_field, '<=', '255.255.255.255', %rest,
# SUBKEY => $rest{'SUBKEY'}. '.LargeContent',
# ENTRYAGGREGATOR => 'AND',
# );
}
else { # negative equation
- $self->_CustomFieldLimit($field, '>', $end_ip, %rest);
+ $self->_CustomFieldLimit($_field, '>', $end_ip, %rest);
$self->_CustomFieldLimit(
- $field, '<', $start_ip, %rest,
+ $_field, '<', $start_ip, %rest,
SUBKEY => $rest{'SUBKEY'}. '.LargeContent',
ENTRYAGGREGATOR => 'OR',
);
}
elsif ( !$negative_op || $single_value ) {
$cfkey .= '.'. $self->{'_sql_multiple_cfs_index'}++ if !$single_value && !$range_op;
- my ($TicketCFs, $CFs) = $self->_CustomFieldJoin( $cfkey, $cfid, $field );
+ my ($ObjectCFs, $CFs) = $self->_CustomFieldJoin( $cfkey, $cfid, $field, $type );
$self->_OpenParen;
# otherwise search in Content and in LargeContent
if ( $column ) {
$self->_SQLLimit( $fix_op->(
- ALIAS => $TicketCFs,
+ ALIAS => $ObjectCFs,
FIELD => $column,
OPERATOR => $op,
VALUE => $value,
}
else {
# need special treatment for Date
- if ( $cf and $cf->Type eq 'DateTime' and $op eq '=' ) {
-
- if ( $value =~ /:/ ) {
- # there is time speccified.
- my $date = RT::Date->new( $self->CurrentUser );
- $date->Set( Format => 'unknown', Value => $value );
- $self->_SQLLimit(
- ALIAS => $TicketCFs,
- FIELD => 'Content',
- OPERATOR => "=",
- VALUE => $date->ISO,
- %rest,
- );
- }
- else {
+ if ( $cf and $cf->Type eq 'DateTime' and $op eq '=' && $value !~ /:/ ) {
# no time specified, that means we want everything on a
# particular day. in the database, we need to check for >
# and < the edges of that day.
my $date = RT::Date->new( $self->CurrentUser );
$date->Set( Format => 'unknown', Value => $value );
- $date->SetToMidnight( Timezone => 'server' );
my $daystart = $date->ISO;
$date->AddDay;
my $dayend = $date->ISO;
$self->_OpenParen;
$self->_SQLLimit(
- ALIAS => $TicketCFs,
+ ALIAS => $ObjectCFs,
FIELD => 'Content',
OPERATOR => ">=",
VALUE => $daystart,
);
$self->_SQLLimit(
- ALIAS => $TicketCFs,
+ ALIAS => $ObjectCFs,
FIELD => 'Content',
- OPERATOR => "<=",
+ OPERATOR => "<",
VALUE => $dayend,
%rest,
ENTRYAGGREGATOR => 'AND',
);
$self->_CloseParen;
- }
}
elsif ( $op eq '=' || $op eq '!=' || $op eq '<>' ) {
- if ( length( Encode::encode_utf8($value) ) < 256 ) {
+ if ( length( Encode::encode( "UTF-8", $value) ) < 256 ) {
$self->_SQLLimit(
- ALIAS => $TicketCFs,
+ ALIAS => $ObjectCFs,
FIELD => 'Content',
OPERATOR => $op,
VALUE => $value,
else {
$self->_OpenParen;
$self->_SQLLimit(
- ALIAS => $TicketCFs,
+ ALIAS => $ObjectCFs,
FIELD => 'Content',
OPERATOR => '=',
VALUE => '',
ENTRYAGGREGATOR => 'OR'
);
$self->_SQLLimit(
- ALIAS => $TicketCFs,
+ ALIAS => $ObjectCFs,
FIELD => 'Content',
OPERATOR => 'IS',
VALUE => 'NULL',
);
$self->_CloseParen;
$self->_SQLLimit( $fix_op->(
- ALIAS => $TicketCFs,
+ ALIAS => $ObjectCFs,
FIELD => 'LargeContent',
OPERATOR => $op,
VALUE => $value,
}
else {
$self->_SQLLimit(
- ALIAS => $TicketCFs,
+ ALIAS => $ObjectCFs,
FIELD => 'Content',
OPERATOR => $op,
VALUE => $value,
$self->_OpenParen;
$self->_OpenParen;
$self->_SQLLimit(
- ALIAS => $TicketCFs,
+ ALIAS => $ObjectCFs,
FIELD => 'Content',
OPERATOR => '=',
VALUE => '',
ENTRYAGGREGATOR => 'OR'
);
$self->_SQLLimit(
- ALIAS => $TicketCFs,
+ ALIAS => $ObjectCFs,
FIELD => 'Content',
OPERATOR => 'IS',
VALUE => 'NULL',
);
$self->_CloseParen;
$self->_SQLLimit( $fix_op->(
- ALIAS => $TicketCFs,
+ ALIAS => $ObjectCFs,
FIELD => 'LargeContent',
OPERATOR => $op,
VALUE => $value,
if ($negative_op) {
$self->_SQLLimit(
- ALIAS => $TicketCFs,
+ ALIAS => $ObjectCFs,
FIELD => $column || 'Content',
OPERATOR => 'IS',
VALUE => 'NULL',
}
else {
$cfkey .= '.'. $self->{'_sql_multiple_cfs_index'}++;
- my ($TicketCFs, $CFs) = $self->_CustomFieldJoin( $cfkey, $cfid, $field );
+ my ($ObjectCFs, $CFs) = $self->_CustomFieldJoin( $cfkey, $cfid, $field, $type );
# reverse operation
$op =~ s/!|NOT\s+//i;
# otherwise search in Content and in LargeContent
if ( $column ) {
$self->SUPER::Limit( $fix_op->(
- LEFTJOIN => $TicketCFs,
- ALIAS => $TicketCFs,
+ LEFTJOIN => $ObjectCFs,
+ ALIAS => $ObjectCFs,
FIELD => $column,
OPERATOR => $op,
VALUE => $value,
}
else {
$self->SUPER::Limit(
- LEFTJOIN => $TicketCFs,
- ALIAS => $TicketCFs,
+ LEFTJOIN => $ObjectCFs,
+ ALIAS => $ObjectCFs,
FIELD => 'Content',
OPERATOR => $op,
VALUE => $value,
}
$self->_SQLLimit(
%rest,
- ALIAS => $TicketCFs,
+ ALIAS => $ObjectCFs,
FIELD => 'id',
OPERATOR => 'IS',
VALUE => 'NULL',
}
push @res, { %$row, ALIAS => $users, FIELD => $subkey };
} elsif ( defined $meta->[0] && $meta->[0] eq 'CUSTOMFIELD' ) {
- my ($queue, $field, $cf_obj, $column) = $self->_CustomFieldDecipher( $subkey );
- my $cfkey = $cf_obj ? $cf_obj->id : "$queue.$field";
+ my ($object, $field, $cf_obj, $column) = $self->_CustomFieldDecipher( $subkey );
+ my $cfkey = $cf_obj ? $cf_obj->id : "$object.$field";
$cfkey .= ".ordering" if !$cf_obj || ($cf_obj->MaxValues||0) != 1;
- my ($TicketCFs, $CFs) = $self->_CustomFieldJoin( $cfkey, ($cf_obj ?$cf_obj->id :0) , $field );
+ my ($ObjectCFs, $CFs) = $self->_CustomFieldJoin( $cfkey, ($cf_obj ?$cf_obj->id :0) , $field );
# this is described in _CustomFieldLimit
$self->_SQLLimit(
ALIAS => $CFs,
QUOTEVALUE => 1,
ENTRYAGGREGATOR => 'AND',
) if $CFs;
- unless ($cf_obj) {
- # For those cases where we are doing a join against the
- # CF name, and don't have a CFid, use Unique to make sure
- # we don't show duplicate tickets. NOTE: I'm pretty sure
- # this will stay mixed in for the life of the
- # class/package, and not just for the life of the object.
- # Potential performance issue.
- require DBIx::SearchBuilder::Unique;
- DBIx::SearchBuilder::Unique->import;
- }
my $CFvs = $self->Join(
TYPE => 'LEFT',
- ALIAS1 => $TicketCFs,
+ ALIAS1 => $ObjectCFs,
FIELD1 => 'CustomField',
TABLE2 => 'CustomFieldValues',
FIELD2 => 'CustomField',
LEFTJOIN => $CFvs,
FIELD => 'Name',
QUOTEVALUE => 0,
- VALUE => $TicketCFs . ".Content",
+ VALUE => $ObjectCFs . ".Content",
ENTRYAGGREGATOR => 'AND'
);
push @res, { %$row, ALIAS => $CFvs, FIELD => 'SortOrder' };
- push @res, { %$row, ALIAS => $TicketCFs, FIELD => 'Content' };
+ push @res, { %$row, ALIAS => $ObjectCFs, FIELD => 'Content' };
} elsif ( $field eq "Custom" && $subkey eq "Ownership") {
# PAW logic is "reversed"
my $order = "ASC";
VALUE => $args{'VALUE'},
OPERATOR => $args{'OPERATOR'},
DESCRIPTION => join( ' ',
- $self->loc('Type'), $args{'OPERATOR'}, $args{'Limit'}, ),
+ $self->loc('Type'), $args{'OPERATOR'}, $args{'VALUE'}, ),
);
}
Takes a paramhash with the fields OPERATOR and VALUE.
OPERATOR is one of =, >, < or !=.
-VALUE is a value to match the ticket\'s priority against
+VALUE is a value to match the ticket's priority against
=cut
Takes a paramhash with the fields OPERATOR and VALUE.
OPERATOR is one of =, >, < or !=.
-VALUE is a value to match the ticket\'s initial priority against
+VALUE is a value to match the ticket's initial priority against
=cut
Takes a paramhash with the fields OPERATOR and VALUE.
OPERATOR is one of =, >, < or !=.
-VALUE is a value to match the ticket\'s final priority against
+VALUE is a value to match the ticket's final priority against
=cut
Takes a paramhash with the fields OPERATOR, TYPE and VALUE.
OPERATOR is one of =, LIKE, NOT LIKE or !=.
- VALUE is a value to match the ticket\'s watcher email addresses against
+ VALUE is a value to match the ticket's watcher email addresses against
TYPE is the sort of watchers you want to match against. Leave it undef if you want to search all of them
$self->Limit(
VALUE => $args{VALUE},
FIELD => "CF"
- .(defined $args{'QUEUE'}? ".{$args{'QUEUE'}}" : '' )
+ .(defined $args{'QUEUE'}? ".$args{'QUEUE'}" : '' )
.".{" . $CF->Name . "}",
OPERATOR => $args{OPERATOR},
CUSTOMFIELD => 1,