[Rt-commit] rt branch, 4.4/sort-by-watcher-cfs, created. rt-4.4.4-84-g2f142b53ae

Craig Kaiser craig at bestpractical.com
Wed Apr 15 10:06:20 EDT 2020


The branch, 4.4/sort-by-watcher-cfs has been created
        at  2f142b53ae591ec8ec2b10185bf5dcedd3109510 (commit)

- Log -----------------------------------------------------------------
commit 2f142b53ae591ec8ec2b10185bf5dcedd3109510
Author: Craig Kaiser <craig at bestpractical.com>
Date:   Wed Apr 15 10:04:05 2020 -0400

    Allow search result sorting based on user attributes
    
    Sort search results based on ticket role users core and custom fields.

diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index b6ccf6ff7e..8e516ed659 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -3902,6 +3902,8 @@ sub _UploadedFile {
 sub GetColumnMapEntry {
     my %args = ( Map => {}, Name => '', Attribute => undef, @_ );
 
+    my $custom_role = RT::CustomRole->new( RT->SystemUser );
+
     # deal with the simplest thing first
     if ( $args{'Map'}{ $args{'Name'} } ) {
         return $args{'Map'}{ $args{'Name'} }{ $args{'Attribute'} };
@@ -3910,6 +3912,13 @@ sub GetColumnMapEntry {
     # complex things
     elsif ( my ( $mainkey, $subkey ) = $args{'Name'} =~ /^(.*?)\.(.+)$/ ) {
         $subkey =~ s/^\{(.*)\}$/$1/;
+
+        # If we are grabbing a custom role attribute
+        unless ( $custom_role->ValidateName( $mainkey ) ) {
+            $mainkey = "CustomRoleAttribute";
+            $subkey  = $args{'Name'};
+        }
+
         return undef unless $args{'Map'}->{$mainkey};
         return $args{'Map'}{$mainkey}{ $args{'Attribute'} }
             unless ref $args{'Map'}{$mainkey}{ $args{'Attribute'} } eq 'CODE';
diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index 15a2851fef..2bf2503428 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -1378,6 +1378,8 @@ sub OrderByCols {
     my @res   = ();
     my $order = 0;
 
+    my $custom_role = RT::CustomRole->new( RT->SystemUser );
+
     foreach my $row (@args) {
         if ( $row->{ALIAS} ) {
             push @res, $row;
@@ -1417,8 +1419,11 @@ sub OrderByCols {
         }
 
         my ( $field, $subkey ) = split /\./, $row->{FIELD}, 2;
+
+        my $is_custom_role = !$custom_role->ValidateName( $field );
+
         my $meta = $FIELD_METADATA{$field};
-        if ( defined $meta->[0] && $meta->[0] eq 'WATCHERFIELD' ) {
+        if ( $is_custom_role || defined $meta->[0] && $meta->[0] eq 'WATCHERFIELD' ) {
             my $type = $meta->[1] || '';
             my $class = $meta->[2] || 'Ticket';
             my $column = $subkey;
@@ -1428,6 +1433,11 @@ sub OrderByCols {
                 $column = $col || 'id';
                 $type = $role ? $role->GroupType : $original_name;
             }
+            elsif ( $is_custom_role ) {
+                my ($role, $col, $original_name) = $self->_CustomRoleDecipher( "\{$field\}\.$column" );
+                $column = $col || 'id';
+                $type = $role ? $role->GroupType : $original_name;
+            }
 
             # cache alias as we want to use one alias per watcher type for sorting
             my $cache_key = join "-", $type, $class;
diff --git a/share/html/Elements/RT__Ticket/ColumnMap b/share/html/Elements/RT__Ticket/ColumnMap
index ae425272e1..697ae94c97 100644
--- a/share/html/Elements/RT__Ticket/ColumnMap
+++ b/share/html/Elements/RT__Ticket/ColumnMap
@@ -332,6 +332,54 @@ $COLUMN_MAP = {
             return \($m->scomp("/Ticket/Elements/PopupTimerLink", id => $_[0]->id ) );
         },
     },
+    CustomRoleAttribute => {
+        title     => sub { return pop @_ },
+        attribute => sub { return shift @_ },
+        value     => sub {
+            my $object    = shift;
+            my $role_attr = pop;
+
+            my ($role_name, $attribute) = $role_attr =~ qr/^([^.]+)\.(.+)$/;
+
+            my $role = RT::CustomRole->new (RT->SystemUser );
+            my ($ret, $msg) = $role->Load( $role_name );
+            unless ( $ret ) {
+                RT->Logger->error( "Could not load custom role '$role_name' : $msg" );
+                return;
+            }
+
+            my $group = RT::Group->new( $session{'CurrentUser'} );
+            ($ret, $msg) = $group->LoadRoleGroup( Name => $role->GroupType, Object => $object );
+            return unless $ret;
+
+            my $users = $group->UserMembersObj( Recursively => 0 );
+
+            my @temp;
+            while ( my $user = $users->Next ) {
+                next unless $user->Id;
+
+                my $identifier = $user->EmailAddress ? $user->EmailAddress : $user->Name;
+
+                if ( $attribute =~ /CustomField/ ) {
+                    my ($custom_field) = $attribute =~ /^CustomField\.\{(.+)\}$/;
+                    my $value = $user->FirstCustomFieldValue( $custom_field ) || '';
+
+                    push @temp, $value;
+                }
+                else {
+                    if ( $user->_Accessible( $attribute, 'read' ) ) {
+                        push @temp, $user->$attribute;
+                    }
+                    else {
+                        RT::Logger->error( "Cannot call $attribute on RT::User record" );
+                    }
+                }
+            }
+            my $out = join(', ', @temp) || '';
+
+            return $out;
+        },
+    }
 };
 </%ONCE>
 <%init>
diff --git a/share/html/Search/Elements/BuildFormatString b/share/html/Search/Elements/BuildFormatString
index ce541f889e..8be53c3511 100644
--- a/share/html/Search/Elements/BuildFormatString
+++ b/share/html/Search/Elements/BuildFormatString
@@ -128,8 +128,32 @@ foreach my $id (keys %queues) {
     next unless $queue->Id;
     $CustomRoles->LimitToObjectId($queue->Id);
 }
-while ( my $Role = $CustomRoles->Next ) {
-    push @fields, "CustomRole.{" . $Role->Name . "}";
+
+my @user_fields = qw/id Name EmailAddress Organization RealName City Country/;
+my $user_cfs    = RT::CustomFields->new( $session{CurrentUser} );
+$user_cfs->Limit( FIELD => 'LookupType', VALUE => RT::User->CustomFieldLookupType );
+while ( my $user_cf = $user_cfs->Next ) {
+    push @user_fields, join '.', 'CustomField', '{' . $user_cf->Name . '}';
+}
+
+# Add all available CustomRoles to the list of sortable columns.
+while ( my $role = $CustomRoles->Next ) {
+
+    # Add all available CustomRoles to the list of sortable columns.
+    for my $user_field (@user_fields) {
+        push @fields, join '.', $role->Name, $user_field;
+    }
+
+    for my $user_field (@user_fields) {
+        push @fields, join '.', $role->Name, $user_field;
+    }
+}
+
+for my $watcher (qw/Owner Requestor Cc AdminCc/) {
+    for my $user_field (@user_fields) {
+        my $field = join '.', $watcher, $user_field;
+        push @fields, $field;
+    }
 }
 
 $m->callback( Fields => \@fields, ARGSRef => \%ARGS );
diff --git a/share/html/Search/Elements/EditSort b/share/html/Search/Elements/EditSort
index 5aa6c43236..b847c1f38c 100644
--- a/share/html/Search/Elements/EditSort
+++ b/share/html/Search/Elements/EditSort
@@ -108,34 +108,14 @@ for my $field (keys %FieldDescriptions) {
     $fields{$field} = $field;
 }
 
-my @user_fields = qw/id Name EmailAddress Organization RealName City Country/;
-my $user_cfs    = RT::CustomFields->new( $session{CurrentUser} );
-$user_cfs->Limit( FIELD => 'LookupType', VALUE => RT::User->CustomFieldLookupType );
-while ( my $user_cf = $user_cfs->Next ) {
-    push @user_fields, join '.', 'CustomField', '{' . $user_cf->Name . '}';
-}
-
-for my $watcher (qw/Owner Requestor Cc AdminCc/) {
-    for my $user_field (@user_fields) {
-        my $field = join '.', $watcher, $user_field;
-        $fields{$field} = $field;
-    }
-}
 
 # Add all available CustomFields to the list of sortable columns.
 my @cfs = grep /^CustomField/, @{$ARGS{AvailableColumns}};
 $fields{$_} = $_ for @cfs;
 
 # Add all available CustomRoles to the list of sortable columns.
-my @roles = grep /^CustomRole/, @{$ARGS{AvailableColumns}};
-for my $role (@roles) {
-    my ($label) = $role =~ /^CustomRole.\{(.*)\}$/;
-    my $value = $role;
-
-    for my $user_field (@user_fields) {
-        $fields{ join '.', $label, $user_field } = join '.', $value, $user_field;
-    }
-}
+my @crs = grep /^.+\./, @{$ARGS{AvailableColumns}};
+$fields{$_} = $_ for @crs;
 
 # Add PAW sort
 $fields{'Custom.Ownership'} = 'Custom.Ownership';

-----------------------------------------------------------------------


More information about the rt-commit mailing list