[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