NAME
RT::Extension::ConditionalCustomFields - CF conditioned by the value of another CF
DESCRIPTION
This plugin provides the ability to display/edit a custom field – called the "conditioned by custom field" throughout this documentation – conditioned by the value of another custom field – the "condition custom field" – for the same object, which can be anything that can have custom fields (ticket, queue, user, group, article or asset).
The condition can be setup on the Admin page for editing the conditioned by custom field. From version 0.99, any custom field can be chosen as the condition custom field (whereas for earlier version, only Select
custom fields were eligible), and you can specify which operator is to be applied against which value(s) for the condition to be met.
Available operators are:
is
The condition is met if and only if the current value of the instanciated conditioned by custom field is equal to the value (or one of the values, see below for multivalued condition) setup for this condition. With
isn't
operator described below,is
operator is the only one which is eligible for selectable custom fields – withSelect
,Combobox
orAutocomplete
type –, since their values are to be selected from a set of values. ForDate
andDateTime
custom fields, this operator is namedon
.isn't
The condition is met if and only if the current value of the instanciated conditioned by custom field is different from the value (or none of the values, see below for multivalued condition) setup for this condition. With
is
operator described above,isn't
operator is the only one which is eligible for selectable custom fields – withSelect
,Combobox
orAutocomplete
type –, since their values are to be selected from a set of values. ForDate
andDateTime
custom fields, this operator is namednot on
.match
The condition is met if and only if the current value of the instanciated conditioned by custom field is included in the value setup for this condition, typically if the current value is a substring of the condition value. As said above, selectable custom fields – with
Select
,Combobox
orAutocomplete
type are not eligible for this operator. Also,Date
andDateTime
custom fields are not eligible for this operator.doesn't match
The condition is met if and only if the current value of the instanciated conditioned by custom field isn't included in the value setup for this condition, typically if the current value isn't a substring of the condition value. As said above, selectable custom fields – with
Select
,Combobox
orAutocomplete
type are not eligible for this operator. Also,Date
andDateTime
custom fields are not eligible for this operator.less than
The condition is met if and only if the current value of the instanciated conditioned by custom field is less than or equal to the value setup for this condition. The comparison is achieved according to some kind of natural sort order, that is: number values are compared as numbers, strings are compared alphabetically, insensitive to case and accents (
a = á
,a = A
). Moreover, IP Adresses (IPv4 and IPv6) are expanded to be compared as expected. As said above, selectable custom fields – withSelect
,Combobox
orAutocomplete
type are not eligible for this operator.greater than
The condition is met if and only if the current value of the instanciated conditioned by custom field is greater than or equal to the value setup for this condition. The comparison is achieved according to some kind of natural sort order, that is: number values are compared as numbers, strings are compared alphabetically, insensitive to case and accents (
a = á
,a = A
), and dates with or without times are compared chronogically. Moreover, IP Adresses (IPv4 and IPv6) are expanded to be compared as expected. As said above, selectable custom fields – withSelect
,Combobox
orAutocomplete
type are not eligible for this operator.between
The condition is met if and only if the current value of the instanciated conditioned by custom field is greater than or equal to the first value setup for this condition and is less than or equal to the second value setup for this condition. That means that when this operator is selected, two values have to be entered. The comparison is achieved according to some kind of natural sort order, that is: number values are compared as numbers, strings are compared alphabetically, insensitive to case and accents (
a = á
,a = A
), and dates with or without times are compared chronogically. Moreover, IP Adresses (IPv4 and IPv6) are expanded to be compared as expected. As said above, selectable custom fields – withSelect
,Combobox
orAutocomplete
type are not eligible for this operator.
As an exception, IPAddressRange
custom fields are not eligible as condition custom fields, since there is not really any sense in comparing two ranges of IP addresses. IPAddress
custom fields, combined with between
operator, should be sufficient for most cases checking whether an IP address is included in a range.
If the condition custom field is selectable – with Select
, Combobox
or Autocomplete
type – it can be multivalued. Then, the condition for an object is met as soon as the condition is met by at least one value of the instanciated conditioned by custom field for this object.
If a custom field is based on another (parent) custom field which is conditioned by, this (child) custom field will of course also be conditioned by (with the same condition as its parent). From version 0.07, the condition can be multivalued, that is: the conditioned custom field can be displayed/edited if the condition custom field has one of these values (In other words: there is an OR
bewteen the values of the condition). The condition custom field can be a select custom field with values defined by CustomFieldValues or an external custom field.
Note that version 0.07 is a complete redesign: the API described below has changed; also, the way that ConditionedBy property is store has changed. If you upgrade from a previous version, you have to reconfigure the custom fields which are conditionned by.
Version 0.99 is also a complete redesign, with API changed, but backward compatibility with previously configured custom fields, assuming the default condition operator is is
.
RT VERSION
Works with RT 4.2 or greater
INSTALLATION
perl Makefile.PL
make
make install
-
May need root permissions
- Patch your RT
-
ConditionalCustomFields
requires a small patch to add necessaryCallbacks
on versions of RT superior to 4.2.3. (The patch has been submitted to BestPractical in order to be included in future RT releases, as of RT 4.4.2, some parts of the patch are already included, but some other parts still required to apply this patch.)For RT 4.2, apply the included patch:
cd /opt/rt4 # Your location may be different patch -p1 < /download/dir/RT-Extension-ConditionalCustomFields/patches/4.2-add-callbacks-to-extend-customfields-capabilities.patch
For RT 4.4.1, apply the included patch:
cd /opt/rt4 # Your location may be different patch -p1 < /download/dir/RT-Extension-ConditionalCustomFields/patches/4.4.1-add-callbacks-to-extend-customfields-capabilities.patch
For RT 4.4.2 or greater, apply the included patch:
cd /opt/rt4 # Your location may be different patch -p1 < /download/dir/RT-Extension-ConditionalCustomFields/patches/4.4.2-add-callbacks-to-extend-customfields-capabilities.patch
For RT 5.0.0 or greater, apply the included patch:
cd /opt/rt5 # Your location may be different patch -p1 < /download/dir/RT-Extension-ConditionalCustomFields/patches/5.0-add-callbacks-to-extend-customfields-capabilities.patch
- Edit your /opt/rt5/etc/RT_SiteConfig.pm
-
If you are using RT 4.2 or greater, add this line:
Plugin('RT::Extension::ConditionalCustomFields');
For RT 4.0, add this line:
Set(@Plugins, qw(RT::Extension::ConditionalCustomFields));
or add
RT::Extension::ConditionalCustomFields
to your existing@Plugins
line. - Clear your mason cache
-
rm -rf /opt/rt5/var/mason_data/obj
- Restart your webserver
CONFIGURATION
Usually, groupings of custom fields, as defined in $CustomFieldGroupings
configuration variable, is not enabled in SelfService. This is the case if you use RT Core. Anyway, some RT instances could have overridden this restriction to enable groupings of custom fields in SelfService.
In this case, you should add to your configuration file (/opt/rt5/etc/RT_SiteConfig.pm) the following line, setting $SelfServiceCustomFieldGroupings
configuration variable to a true value:
Set($SelfServiceCustomFieldGroupings, 1);
METHODS
ConditionalCustomFields
adds a ConditionedBy
property, that is a condition CustomField, an operator and one or more values, along with the following methods, to conditioned by CustomField objects:
SetConditionedBy CF, OP, VALUE
Set the ConditionedBy
property for this CustomField object to CustomField CF
with operator set to OP
and value set to VALUE
. CF
should be an existing CustomField object or the id of an existing CustomField object, or the name of an unambiguous existing CustomField object. OP
should be is
, isn't
, match
, doesn't match
, less than
, greater than
or between
. VALUE
should be a string or an anonymous array of strings (for selectable custom fields or between
operator). Current user should have SeeCustomField
and ModifyCustomField
rights for this conditioned by CustomField and SeeCustomField
right for the condition CustomField. Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
ConditionedBy
Returns the current ConditionedBy
property for this conditioned by CustomField object as a hash with keys CF
containing the id of the condition CustomField, op
and vals
containing the condition operator as string, and the condition value as an array of strings (so we can store several values for selectable custom fields or between
operator, but generally the vals
array includes only one string). If neither this conditioned by CustomField nor one of its ancestor is conditioned by the CF
condition CustomField, that is: if their ConditionedBy
property is not (recursively) defined, returns undef
. Current user should have SeeCustomField
right for both this conditioned by CustomField and the condition CustomField which this CustomField is conditioned recursively by. "Recursively" means that this method will search for a ConditionedBy
property for this CustomField object, then for the CustomField this one is BasedOn
, and so on until it finds an ancestor Category
with a ConditionedBy
property or, the CustomField which is being looked up, is not based on any ancestor Category
.
INITIALDATA
Also, ConditionalCustomFields
allows to set the ConditionedBy
property when creating CustomFields from an initialdata file, with one of the following syntaxes:
@CustomFields = (
{
Name => 'Condition',
Type => 'SelectSingle',
RenderType => 'Dropdown',
Queue => [ 'General' ],
LookupType => 'RT::Queue-RT::Ticket',
Values => [
{ Name => 'Passed', SortOrder => 0 },
{ Name => 'Failed', SortOrder => 1 },
{ Name => 'Schrödingerized', SortOrder => 2 },
],
Pattern => '(?#Mandatory).',
DefaultValues => [ 'Failed' ],
},
{
Name => 'Conditioned with cf name and value',
Type => 'FreeformSingle',
Queue => [ 'General' ],
LookupType => 'RT::Queue-RT::Ticket',
ConditionedByCF => 'Condition',
ConditionedBy => 'Passed',
},
{
Name => 'Conditioned with cf id and value',
Type => 'FreeformSingle',
Queue => [ 'General' ],
LookupType => 'RT::Queue-RT::Ticket',
ConditionedByCF => 66,
ConditionOp => "isn't",
ConditionedBy => 'Failed',
},
{
Name => 'Conditioned with multiple values',
Type => 'Freeform',
MaxValues => 1,
Queue => [ 'General' ],
LookupType => 'RT::Queue-RT::Ticket',
ConditionedByCF => 'Condition',
ConditionedBy => ['Passed', 'Schrödingerized'],
},
);
This examples creates a Select
condition CustomField, named Condition
and three conditioned by CustomFields. CustomField Condition
should have the value Passed
, for CustomField Conditioned with cf name and value
to be displayed or edited. CustomField Condition
should not have the value Failed
for CustomField Conditioned with cf id and value
to be displayed or edited. CustomField Condition
should have one of the values Passed
or Schrödingerized
for CustomField Conditioned with multiple values
to be displayed or edited.
Additional fields for an element of @CustomFields
are:
ConditonedByCF
-
The condition CustomField that this new CustomField should conditioned by. It can be either the
id
or theName
of a previously created CustomField. This implies that the condition CustomField should be declared before this one in the initialdata file, or it should already exist. WhenConditionedByCF
attribute is set,ConditionedBy
field should always also be set. ConditonedBy
-
The value as a
string
of the condition CustomField defined by theConditionedByCF
field (which is mandatory). ConditonOp
-
The operator as a
string
to use for comparison, eitheris
,isn't
,match
,doesn't match
,less than
,greater than
orbetween
. This field is optional, defaults tois
.
TEST SUITE
ConditionalCustomFields
comes with a fairly complete test suite. As for every RT extention, to run it, you will need a installed RT
, set up in development mode. But, since ConditionalCustomFields
operates dynamically to show or hide custom fields, most of its magic happens in Javascript
. Therefore, the test suite requires a scriptable headless browser with Javascript
capabilities. So you also need to install PhantomJS, along with WWW::Mechanize::PhantomJS and Selenium::Remote::Driver.
It should be noted that with version 0.99, the number of cases to test has exponentially expanded. Not only any object which can have custom fields (ticket, queue, user, group, article or asset) should be tested. But also, any type of custom fields (Select
, Freeform
, Text
, Wikitext
, Image
, Binary
, Combobox
, Autocomplete
, Date
, DateTime
and IPAddress
) should be tested both for condition custom field and conditioned by custom field. And this both for Single
and Multiple
versions (when available) of each type of custom fields. Select
custom fields should also be tested for each render type (Select box
, List
, Dropdown
and also Chosen
when the number of values is greater than ten). Adding to these required unitary tests, some special cases should also be included, for instance when a condition custom field is in turn conditioned by another condition custom field, or when a condition custom field is not applied to a queue, etc. Eventually, the test suite includes 1929 unitary tests and 64 test files. Nevertheless some special cases may have been left over, so you're encourage to fill a bug report, so they can be fixed.
AUTHOR
Gérald Sédrati-Dinet <gibus@easter-eggs.com>
REPOSITORY
https://github.com/gibus/RT-Extension-ConditionalCustomFields
BUGS
All bugs should be reported via email to
bug-RT-Extension-ConditionalCustomFields@rt.cpan.org
or via the web at
LICENSE AND COPYRIGHT
This software is Copyright (c) 2017-2019 by Gérald Sédrati-Dinet, Easter-Eggs
This is free software, licensed under:
The GNU General Public License, Version 3, June 2007