Getting Custom Fields for a User

Good Evening,

I’m trying to obtain the list of custom fields for the current user so that I can take certain decisions based on these values.

I’ve had a look at the code in ‘Admin/Elements/EditCustomFields’ and adapted (I think) accordingly but it’s not returning any values:

I’d appreciate any assistance that you can offer.

Here’s the code of put into ‘local/html/Callbacks/MyCallbacks/Ticket/Elements/EditCustomFields/MassageCustomFields’

<%$session{‘CurrentUser’}->RealName%>
% while (my $CustomFieldObj = $CustomFields->Next) {
<% $CustomFieldObj->id %><% $CustomFieldObj->Name %>

%}

<%INIT>
my $CustomFields = RT::CustomFields->new($session{‘CurrentUser’});
$CustomFields->UnLimit;
$CustomFields->LimitToLookupType( $LookupType ) if $LookupType;
</%INIT>

<%ARGS>
$LookupType => ‘RT::Queue-RT::User’
</%ARGS>

Thanks in advance

Lee

I’m trying to obtain the list of custom fields for the current user so that I can take certain decisions based on these values.

I’ve had a look at the code in ‘Admin/Elements/EditCustomFields’ and adapted (I think) accordingly but it’s not returning any values:

[snip]

<%ARGS>
$LookupType => ‘RT::Queue-RT::User’
</%ARGS>

RT::Queue-RT::User isn’t a valid LookupType. It’s just RT::User. See
the top of RT::CustomField for the valid types (or the html of the
Create CF admin page).

Thomas

RT::Queue-RT::User isn’t a valid LookupType. It’s just RT::User. See
the top of RT::CustomField for the valid types (or the html of the
Create CF admin page).

Thomas

Thanks for the quick response Thomas, bit too liberal copying on my part
there.

I’ve removed the LookupType filter completely but stil not getting any
records returned or any errors generated?

RT::Queue-RT::User isn’t a valid LookupType. It’s just RT::User. See
the top of RT::CustomField for the valid types (or the html of the
Create CF admin page).

Thomas

Thanks for the quick response Thomas, bit too liberal copying on my part
there.

I’ve removed the LookupType filter completely but stil not getting any
records returned or any errors generated?

If you have user object then you can just call my $cfs = $user->CustomFIelds;.
You can take a look at CustomFIelds method in lib/RT/Record.pm.

Even if you don’t have user object then create one:

my $cfs = RT::User->new( RT->SystemUser )->CustomFields;

Use $session{CurrentUser} instead of SystemUser if it’s web interface and
you want to respect ACLs.


List info: The rt-devel Archives

Best regards, Ruslan.

If you have user object then you can just call my $cfs = $user->CustomFIelds;.
You can take a look at CustomFIelds method in lib/RT/Record.pm.

Even if you don’t have user object then create one:

my $cfs = RT::User->new( RT->SystemUser )->CustomFields;

Use $session{CurrentUser} instead of SystemUser if it’s web interface and
you want to respect ACLs.

Hi Ruslan,

Thanks for that. Looking at the perldoc for User.pm doesn’t give any
mention of that but I guess it’s inherited from Record.pm

Think I’ve sussed out the problem, I was trying to run this as a none
privileged user but it didn’t have access to SeeCustomFields based on
the code in CustomFields->Next:

return $self->Next unless $CF->CurrentUserHasRight(‘SeeCustomField’);

I tried granting the SeeCustomField and ModifyCustomField rights on the
specific customer queue but that still didn’t make the fields appear.

In the end I granted those two rights onto the global unprivileged group
which has made the fields appear but it seems a bit too open to me.

Eventually I think applying those rights to the specific custom field
has given what I needed.

Would this generally be the right way to do it?

Thanks again

Lee

Hi Ruslan,

Thanks for that. Looking at the perldoc for User.pm doesn’t give any mention
of that but I guess it’s inherited from Record.pm

Right. In theory CFs can be on any object in the system, so methods
are in Record.pm.

Think I’ve sussed out the problem, I was trying to run this as a none
privileged user but it didn’t have access to SeeCustomFields based on the
code in CustomFields->Next:

return $self->Next unless $CF->CurrentUserHasRight(‘SeeCustomField’);

I tried granting the SeeCustomField and ModifyCustomField rights on the
specific customer queue but that still didn’t make the fields appear.

Queues has nothing to do with Users and your “customer queue” is just
logical agreement RT doesn’t know about. So custom fields applied to
users’ records can not inherit rights from queues, may be from groups,
but it’s not implemented. More about rights below.

In the end I granted those two rights onto the global unprivileged group
which has made the fields appear but it seems a bit too open to me.

Eventually I think applying those rights to the specific custom field has
given what I needed.

Would this generally be the right way to do it?

The most correct and safe way is to grant rights to groups for every
custom field. May be it’s not flexible enough, but this the only way
that properly isolates access.

Some objects in RT announce rights and you can grant particular
principal (group/user/role) to have a right on an object. These
objects are Tickets, CustomFields, Queues, Groups… Nobody wants to
grant rights on every ticket, so there is concept of rights
inheritance when right is check on ticket, but is set on queue. Every
object inherits rights from system level.

All custom fields in RT use one right “SeeCustomField” that is checked
to decide whether user can see or not the field. This means that if
you grant this right on global level to a group then this group can
see ALL custom fields in the system. May be they can not see them in
UI by pointing and clicking, but low level code would hide them.
Extension or custom page may expose them and it wouldn’t be its fault.

Rights inheritance for tickets is “simple”. Every ticket is in one and
only one queue at a moment. You grant rights on queue level.

Rights inheritance for custom fields is complex. Different custom
fields have different inheritance chains. For custom fields that apply
to Users, it’s system → custom field, but for tickets’ CFs it’s
system → queue → custom field. Also, the same ticket custom field
can be applied to multiple queues. It’s even more complicated under
the hood. So granting SeeCustomField to a group on queue level to give
users ability to see all CFs on tickets in this queue may be cool
feature, but it’s too complex to implement right and it’s considered
experimental with known issues.

Best regards, Ruslan.

Hi Ruslan,

Thanks for that. Looking at the perldoc for User.pm doesn’t give any mention
of that but I guess it’s inherited from Record.pm

Right. In theory CFs can be on any object in the system, so methods
are in Record.pm.

Thanks for the detailed reply Ruslan it’s really helped me understand
things. In the meantime I’ve read about the RT:SystemUSer which may do
things more like I want to as all I need to be able to do is get the
values for the users custom fields when creating/editing a ticket.

I’m now a bit stuck on how to retrieve the values for the custom fields.
Perhaps if I explain more what I’m trying to do someone be so kind as to
explain the bit i’ve missed/got wrong:

  1. Requestor creates a ticket
  2. Upon the new ticket window loading, lookup the Account ID stored in
    the users custom field
  3. Based on the Account ID display a list of services (stored in a
    seperate database/CRM) in a dropdown ← got this bit working
    independently just not with RT.
  4. Store the id of the selected service into a hidden ticket custom field.

I’ve got a few more processes that I wish to get working but the basic
process is the same.

So far I’ve got as far as coding the following test routine is
MassageCustomFields but can’t get it to show the values of the
associated current user:

% if ($CustomFields->First) {
Ok we’ve found some custom fields:

% $CustomFields->GotoFirstItem;

<% $session{‘CurrentUser’}->id %>
<-------- This Id displays fine
% while ( my $CustomField = $CustomFields->Next) {
<% loc($CustomField->Name) %> <------ Name of the custom field shows up
% $CustomField->Load($CustomField->Name);
<% $CustomField->ValuesForObject($session{‘CurrentUser’}) %>


% }
% }

On the last line it returns a reference to ‘RT::ObjectCustomFieldValues’
but I can’t figure out how to get the currently selected/filled in value.

Once again, thanks for all your help so far.

Lee

Ruslan from phone.

Hi Ruslan,

Thanks for that. Looking at the perldoc for User.pm doesn’t give any
mention
of that but I guess it’s inherited from Record.pm

Right. In theory CFs can be on any object in the system, so methods
are in Record.pm.

Thanks for the detailed reply Ruslan it’s really helped me understand
things. In the meantime I’ve read about the RT:SystemUSer which may do
things more like I want to as all I need to be able to do is get the values
for the users custom fields when creating/editing a ticket.

I’m now a bit stuck on how to retrieve the values for the custom fields.
Perhaps if I explain more what I’m trying to do someone be so kind as to
explain the bit i’ve missed/got wrong:

  1. Requestor creates a ticket
  2. Upon the new ticket window loading, lookup the Account ID stored in
    the users custom field
  3. Based on the Account ID display a list of services (stored in a
    seperate database/CRM) in a dropdown ← got this bit working independently
    just not with RT.
  4. Store the id of the selected service into a hidden ticket custom field.

I’ve got a few more processes that I wish to get working but the basic
process is the same.

So far I’ve got as far as coding the following test routine is
MassageCustomFields but can’t get it to show the values of the associated
current user:

% if ($CustomFields->First) {
Ok we’ve found some custom fields:

% $CustomFields->GotoFirstItem;

<% $session{‘CurrentUser’}->id %>
<-------- This Id displays fine
% while ( my $CustomField = $CustomFields->Next) {
<% loc($CustomField->Name) %> <------ Name of the custom field shows up
% $CustomField->Load($CustomField->Name);
<% $CustomField->ValuesForObject($session{‘CurrentUser’}) %>


% }
% }

On the last line it returns a reference to ‘RT::ObjectCustomFieldValues’
but I can’t figure out how to get the currently selected/filled in value.

First of all every object has CustomFieldValues method that return the same
thing. So after getting name of a CF you can call it on
§session{CurrentUser}->UserObj.

ObjectCustomFieldValues is just another collection you walk with Next and
while loop. If you know for sure that all fields are single value then you
can use FirstCustomFieldValue.

Once again, thanks for all your help so far.

Lee

List info:
The rt-devel Archives

First of all every object has CustomFieldValues method that return the
same thing. So after getting name of a CF you can call it on
§session{CurrentUser}->UserObj.

ObjectCustomFieldValues is just another collection you walk with Next
and while loop. If you know for sure that all fields are single value
then you can use FirstCustomFieldValue.

Excellent, thanks to your help think I’ve got there:

% while ( my $CustomField = $CustomFields->Next) {
<% loc($CustomField->Name) %>
% my $cfValues =
$session{CurrentUser}->UserObj->CustomFieldValues($CustomField->Name);
<%
$session{CurrentUser}->UserObj->FirstCustomFieldValue($CustomField->Name) %>


% }
% }

The above code shows how I got the first value but also found I could
get it with:

$session{CurrentUser}->UserObj->FirstCustomFieldValue($CustomField->Id)

or through a loop (which may help with future tasks):

% while ( my $cfValue = $cfValues->Next) {
<%$cfValue->Content %>
% }

Your help is very much appreciated. Now, to figure out how to do a add
a hidden custom field :-~

Lee

First of all every object has CustomFieldValues method that return the
same thing. So after getting name of a CF you can call it on
§session{CurrentUser}->UserObj.

ObjectCustomFieldValues is just another collection you walk with Next
and while loop. If you know for sure that all fields are single value
then you can use FirstCustomFieldValue.

Excellent, thanks to your help think I’ve got there:

% while ( my $CustomField = $CustomFields->Next) {
<% loc($CustomField->Name) %>
% my $cfValues = $session{CurrentUser}->UserObj->CustomFieldValues($CustomField->Name);
<% $session{CurrentUser}->UserObj->FirstCustomFieldValue($CustomField->Name)
%>


% }
% }

The above code shows how I got the first value but also found I
could get it with:

$session{CurrentUser}->UserObj->FirstCustomFieldValue($CustomField->Id)

or through a loop (which may help with future tasks):

% while ( my $cfValue = $cfValues->Next) {
<%$cfValue->Content %>
% }

Your help is very much appreciated. Now, to figure out how to do a
add a hidden custom field :-~

If you like FirstCustomFieldValue, you may also like
CustomFieldValuesAsString which is located right below it in the docs
for RT::Record

-kevin

If you have user object then you can just call my $cfs = $user->CustomFIelds;.
You can take a look at CustomFIelds method in lib/RT/Record.pm.

Even if you don’t have user object then create one:

my $cfs = RT::User->new( RT->SystemUser )->CustomFields;

Use $session{CurrentUser} instead of SystemUser if it’s web interface and
you want to respect ACLs.

Hi Ruslan,

Thanks for that. Looking at the perldoc for User.pm doesn’t give any
mention of that but I guess it’s inherited from Record.pm

Think I’ve sussed out the problem, I was trying to run this as a none
privileged user but it didn’t have access to SeeCustomFields based on
the code in CustomFields->Next:

return $self->Next unless $CF->CurrentUserHasRight(‘SeeCustomField’);

I tried granting the SeeCustomField and ModifyCustomField rights on the
specific customer queue but that still didn’t make the fields appear.

In the end I granted those two rights onto the global unprivileged group
which has made the fields appear but it seems a bit too open to me.

Eventually I think applying those rights to the specific custom field
has given what I needed.

Would this generally be the right way to do it?

Thanks again

Lee

Sorry ignore this reply, got stuck in outbox.On 27/04/2012 19:38, Lee Wilson wrote:

On 16/04/2012 15:25, Ruslan Zakirov wrote:

If you have user object then you can just call my $cfs =
$user->CustomFIelds;.
You can take a look at CustomFIelds method in lib/RT/Record.pm.

Even if you don’t have user object then create one:

my $cfs = RT::User->new( RT->SystemUser )->CustomFields;

Use $session{CurrentUser} instead of SystemUser if it’s web interface and
you want to respect ACLs.

Hi Ruslan,

Thanks for that. Looking at the perldoc for User.pm doesn’t give any
mention of that but I guess it’s inherited from Record.pm

Think I’ve sussed out the problem, I was trying to run this as a none
privileged user but it didn’t have access to SeeCustomFields based on
the code in CustomFields->Next:

return $self->Next unless $CF->CurrentUserHasRight(‘SeeCustomField’);

I tried granting the SeeCustomField and ModifyCustomField rights on the
specific customer queue but that still didn’t make the fields appear.

In the end I granted those two rights onto the global unprivileged group
which has made the fields appear but it seems a bit too open to me.

Eventually I think applying those rights to the specific custom field
has given what I needed.

Would this generally be the right way to do it?

Thanks again

Lee

List info: The rt-devel Archives