rt 4.0.23
[freeside.git] / rt / lib / RT / Tickets.pm
index 06b17e2..c826b6f 100755 (executable)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2013 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)
@@ -89,7 +89,6 @@ use base 'RT::SearchBuilder';
 sub Table { 'Tickets'}
 
 use RT::CustomFields;
-use DBIx::SearchBuilder::Unique;
 
 # Configuration Tables:
 
@@ -142,9 +141,9 @@ our %FIELD_METADATA = (
     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
@@ -443,10 +442,6 @@ sub _LinkLimit {
     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' ) {
@@ -473,6 +468,7 @@ sub _LinkLimit {
         $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;
@@ -977,13 +973,18 @@ sub _WatcherLimit {
     }
     $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)?$/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(
@@ -1021,7 +1022,7 @@ sub _WatcherLimit {
         $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;
@@ -1046,7 +1047,7 @@ sub _WatcherLimit {
                 VALUE      => "$group_members.MemberId",
                 QUOTEVALUE => 0,
             );
-            my $users = $self->Join(
+            $users ||= $self->Join(
                 TYPE            => 'LEFT',
                 ALIAS1          => $group_members,
                 FIELD1          => 'MemberId',
@@ -1072,10 +1073,10 @@ sub _WatcherLimit {
     } 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',
@@ -1092,6 +1093,7 @@ sub _WatcherLimit {
         );
     }
     $self->_CloseParen;
+    return ($groups, $group_members, $users);
 }
 
 sub _RoleGroupsJoin {
@@ -1342,33 +1344,44 @@ sub _WatcherMembershipLimit {
 
 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 ( $object ) {
+        my $record_class = RT::CustomField->RecordClassFromLookupType($lookuptype);
+        $applied_to = $record_class->new( $self->CurrentUser );
+        $applied_to->Load( $object );
 
-        if ( $q->id ) {
-            # $queue = $q->Name; # should we normalize the queue?
-            $cf = $q->CustomField( $field );
+        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
@@ -1381,9 +1394,11 @@ sub _CustomFieldDecipher {
     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
@@ -1392,8 +1407,14 @@ Factor out the Join of custom fields so we can use it for sorting too
 
 =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} )
@@ -1402,17 +1423,21 @@ sub _CustomFieldJoin {
                  $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'
@@ -1444,7 +1469,7 @@ sub _CustomFieldJoin {
             LEFTJOIN        => $CFs,
             ENTRYAGGREGATOR => 'AND',
             FIELD           => 'LookupType',
-            VALUE           => 'RT::Queue-RT::Ticket',
+            VALUE           => $type,
         );
         $self->SUPER::Limit(
             LEFTJOIN        => $CFs,
@@ -1453,7 +1478,7 @@ sub _CustomFieldJoin {
             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',
@@ -1461,28 +1486,29 @@ sub _CustomFieldJoin {
             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
@@ -1501,12 +1527,16 @@ use Regexp::Common::net::CIDR;
 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
@@ -1547,15 +1577,6 @@ sub _CustomFieldLimit {
     }
 
     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 ) {
@@ -1602,16 +1623,16 @@ sub _CustomFieldLimit {
 
     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,
@@ -1634,11 +1655,11 @@ sub _CustomFieldLimit {
         $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',
             ); 
@@ -1646,20 +1667,20 @@ sub _CustomFieldLimit {
             # 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',
             );  
@@ -1671,7 +1692,7 @@ sub _CustomFieldLimit {
     } 
     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;
 
@@ -1682,7 +1703,7 @@ sub _CustomFieldLimit {
         # otherwise search in Content and in LargeContent
         if ( $column ) {
             $self->_SQLLimit( $fix_op->(
-                ALIAS      => $TicketCFs,
+                ALIAS      => $ObjectCFs,
                 FIELD      => $column,
                 OPERATOR   => $op,
                 VALUE      => $value,
@@ -1708,7 +1729,7 @@ sub _CustomFieldLimit {
                     $self->_OpenParen;
 
                     $self->_SQLLimit(
-                        ALIAS    => $TicketCFs,
+                        ALIAS    => $ObjectCFs,
                         FIELD    => 'Content',
                         OPERATOR => ">=",
                         VALUE    => $daystart,
@@ -1716,7 +1737,7 @@ sub _CustomFieldLimit {
                     );
 
                     $self->_SQLLimit(
-                        ALIAS    => $TicketCFs,
+                        ALIAS    => $ObjectCFs,
                         FIELD    => 'Content',
                         OPERATOR => "<",
                         VALUE    => $dayend,
@@ -1727,9 +1748,9 @@ sub _CustomFieldLimit {
                     $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,
@@ -1740,14 +1761,14 @@ sub _CustomFieldLimit {
                 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',
@@ -1755,7 +1776,7 @@ sub _CustomFieldLimit {
                     );
                     $self->_CloseParen;
                     $self->_SQLLimit( $fix_op->(
-                        ALIAS           => $TicketCFs,
+                        ALIAS           => $ObjectCFs,
                         FIELD           => 'LargeContent',
                         OPERATOR        => $op,
                         VALUE           => $value,
@@ -1766,7 +1787,7 @@ sub _CustomFieldLimit {
             }
             else {
                 $self->_SQLLimit(
-                    ALIAS    => $TicketCFs,
+                    ALIAS    => $ObjectCFs,
                     FIELD    => 'Content',
                     OPERATOR => $op,
                     VALUE    => $value,
@@ -1777,14 +1798,14 @@ sub _CustomFieldLimit {
                 $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',
@@ -1792,7 +1813,7 @@ sub _CustomFieldLimit {
                 );
                 $self->_CloseParen;
                 $self->_SQLLimit( $fix_op->(
-                    ALIAS           => $TicketCFs,
+                    ALIAS           => $ObjectCFs,
                     FIELD           => 'LargeContent',
                     OPERATOR        => $op,
                     VALUE           => $value,
@@ -1826,7 +1847,7 @@ sub _CustomFieldLimit {
 
             if ($negative_op) {
                 $self->_SQLLimit(
-                    ALIAS           => $TicketCFs,
+                    ALIAS           => $ObjectCFs,
                     FIELD           => $column || 'Content',
                     OPERATOR        => 'IS',
                     VALUE           => 'NULL',
@@ -1840,7 +1861,7 @@ sub _CustomFieldLimit {
     }
     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;
@@ -1849,8 +1870,8 @@ sub _CustomFieldLimit {
         # 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,
@@ -1859,8 +1880,8 @@ sub _CustomFieldLimit {
         }
         else {
             $self->SUPER::Limit(
-                LEFTJOIN   => $TicketCFs,
-                ALIAS      => $TicketCFs,
+                LEFTJOIN   => $ObjectCFs,
+                ALIAS      => $ObjectCFs,
                 FIELD      => 'Content',
                 OPERATOR   => $op,
                 VALUE      => $value,
@@ -1869,7 +1890,7 @@ sub _CustomFieldLimit {
         }
         $self->_SQLLimit(
             %rest,
-            ALIAS      => $TicketCFs,
+            ALIAS      => $ObjectCFs,
             FIELD      => 'id',
             OPERATOR   => 'IS',
             VALUE      => 'NULL',
@@ -1979,10 +2000,10 @@ sub OrderByCols {
             }
             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,
@@ -1992,19 +2013,9 @@ sub OrderByCols {
                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',
@@ -2013,12 +2024,12 @@ sub OrderByCols {
                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";
@@ -3144,7 +3155,7 @@ sub LimitCustomField {
     $self->Limit(
         VALUE => $args{VALUE},
         FIELD => "CF"
-            .(defined $args{'QUEUE'}? ".{$args{'QUEUE'}}" : '' )
+            .(defined $args{'QUEUE'}? ".$args{'QUEUE'}" : '' )
             .".{" . $CF->Name . "}",
         OPERATOR    => $args{OPERATOR},
         CUSTOMFIELD => 1,