[Rt-commit] rt branch, 4.4/core-admincondionsandactions-extension, repushed

Dustin Collins strega at bestpractical.com
Tue Oct 18 22:45:45 EDT 2016


The branch 4.4/core-admincondionsandactions-extension was deleted and repushed:
       was 4cb43e7933ace99924206cc4be52606f0a2ba126
       now 457d0058a7970083e2353efa8532f07519cc0484

1:  4cb43e7 ! 1:  457d005 Merge RT-Extension-AdminConditionsAndActions
    @@ -9,320 +9,259 @@
     --- /dev/null
     +++ b/docs/conditions_and_actions.pod
     @@
    -+NAME
    -+    RT-Extension-AdminConditionsAndActions - Admin Conditions And Actions
    -+
    -+DESCRIPTION
    -+    A web UI for managing RT conditions and actions.
    -+
    -+RT VERSIONS
    -+    This extension is compatible with RT 4.0 and RT 4.2.
    -+
    -+INSTALLATION
    -+    perl Makefile.PL
    -+    make
    -+    make install
    -+        May need root permissions
    -+
    -+    Edit your /opt/rt4/etc/RT_SiteConfig.pm
    -+        If you are using RT 4.2 or greater, add this line:
    -+
    -+            Plugin('RT::Extension::AdminConditionsAndActions');
    -+
    -+        For RT 4.0, add this line:
    -+
    -+            Set(@Plugins, qw(RT::Extension::AdminConditionsAndActions));
    -+
    -+        or add RT::Extension::AdminConditionsAndActions to your existing
    -+        @Plugins line.
    -+
    -+        You can customize Condition/Action list format by config
    -+        %AdminSearchResultFormat, e.g.
    -+
    -+            Set(%AdminSearchResultFormat,
    -+                ...
    -+                Conditions =>
    -+                    q{'<a href="__WebPath__/Admin/Conditions/Modify.html?&id=__id__">__id__</a>/TITLE:#'}
    -+                    .q{,'<a href="__WebPath__/Admin/Conditions/Modify.html?id=__id__">__Name__</a>/TITLE:Name'}
    -+                    .q{,'__Description__','__UsedBy__},
    -+                Actions =>
    -+                    q{'<a href="__WebPath__/Admin/Actions/Modify.html?&id=__id__">__id__</a>/TITLE:#'}
    -+                    .q{,'<a href="__WebPath__/Admin/Actions/Modify.html?id=__id__">__Name__</a>/TITLE:Name'}
    -+                    .q{,'__Description__','__UsedBy__},
    -+            );
    -+
    -+    Clear your mason cache
    -+            rm -rf /opt/rt4/var/mason_data/obj
    -+
    -+    Restart your webserver
    -+
    -+USAGE
    -+    The core building blocks of scrips in RT are the conditions and actions
    -+    you select when configuring the scrip. A condition defines the criteria
    -+    for an action to run in the context of the current transaction. The
    -+    result is true or false: if true, the condition is satisfied and the
    -+    action runs, if false, the action is skipped. Actions define something
    -+    to be done when a condition is true and they can be anything you can
    -+    capture in code, either changing things in RT or calling out to other
    -+    systems, DBs, or APIs.
    -+
    -+    You can view all of the scrips that come standard with RT by going to
    -+    Tools > Global > Scrips (RT 4.0) or Admin > Global > Scrips (RT 4.2). In
    -+    the scrips list you'll see each has a condition and an action and these
    -+    are provided with the initial RT installation. You might also see
    -+    additional conditions and actions added by extensions or through a local
    -+    customization.
    -+
    -+    This extension provides a web UI to allow you to easily register your
    -+    own conditions and actions in RT, making it easier than ever to
    -+    customize RT for your specific needs.
    -+
    -+  User Defined Conditions and Actions
    -+    The simplest way to add a custom condition or action is to create a new
    -+    scrip and select "User Defined" as the Condition or Action. You can then
    -+    put your custom code right in the "User Defined" boxes on the bottom of
    -+    the scrip modification page.
    -+
    -+    However, you might prefer writing your condition or action in a module
    -+    with the code in a file. This allows you to track it in version control
    -+    and call it from other places like rt-crontool. The following sections
    -+    describe how to create these modules.
    -+
    -+  Custom Conditions
    -+    Let's assume you have a custom lifecycle with a status called 'review'
    -+    and you want an 'On Review Needed' condition so you can trigger actions
    -+    when a ticket is put in review status. You notice RT already has 'On
    -+    Resolve' and other similar conditions, so you look at the configuration
    -+    at Admin > Global > Conditions and click on 'On Resolve' (in RT 4.0,
    -+    select Tools > Global > Conditions.)
    -+
    -+    The condition has a Name, which is displayed in the Condition dropdown
    -+    when you create a scrip, and a Description to identify it. The Condition
    -+    Module is the RT module that executes the condition, in this case
    -+    StatusChange. You can find the code in
    -+    /opt/rt4/lib/RT/Condition/StatusChange.pm and view the documentation on
    -+    the Best Practical "documentation site". (Confirm your RT version when
    -+    checking the documentation.)
    -+
    -+    Parameters to Pass shows the actual parameter that is passed to the
    -+    module when this condition is executed. When you look at the module
    -+    documentation it makes sense when you see that StatusChange accepts a
    -+    valid status and returns true if the transaction is setting the status
    -+    to the provided value. Finally, Applicable Transaction Types lists the
    -+    transactions for which this condition will run, and in this case it's
    -+    Status transactions.
    -+
    -+    This is really close to what we might need for our 'On Review Needed' so
    -+    you can click the Copy Condition button to copy the current condition.
    -+    On the new condition page, you can update the Name and Description and
    -+    set the Parameters to Pass to 'review'. Then click save and you have
    -+    your new condition. You can now create a new scrip and select it from
    -+    the Condition dropdown.
    -+
    -+  Custom Condition Module
    -+    Now assume we have an additional requirement to check if a custom field
    -+    value 'Special' is selected when we check the review status. For this
    -+    one we'll need to write some code. To start, create a new file for your
    -+    new SpecialReviewNeeded module here:
    -+
    -+        /opt/rt4/local/lib/RT/Condition/SpecialReviewNeeded.pm
    -+
    -+    Creating it in the local directory will keep it safe when you apply RT
    -+    upgrades in the future.
    -+
    -+    The basics of a condition module are as follows:
    -+
    -+        package RT::Condition::SpecialReviewNeeded;
    -+
    -+        use strict;
    -+        use warnings;
    -+        use base 'RT::Condition';
    -+
    -+        sub IsApplicable {
    -+            my $self = shift;
    -+
    -+            # Your code here
    -+
    -+            return 1; # True if condition is true, false if not
    -+        }
    -+
    -+        1; # Don't forget module needs this
    -+
    -+    IsApplicable is the method you will override from the RT::Condition base
    -+    class. The return value of this method, true or false, determines
    -+    whether the condition passes or not.
    -+
    -+    $self gives you access to the ticket object and transaction object via:
    -+
    -+        $self->TransactionObj
    -+        $self->TicketObj
    -+
    -+    These are your main hooks into the current ticket and transaction.
    -+
    -+    To check review status and the custom field value, we might add
    -+    something like this:
    -+
    -+        # Setting status to review?
    -+        return 0 unless $self->TransactionObj->Type eq 'Status'
    -+            and $self->TransactionObj->NewValue eq 'review';
    -+
    -+        # Is 'Special' set to Yes?
    -+        return 0 unless $self->TicketObj->FirstCustomFieldValue('Special') eq 'Yes';
    -+
    -+        return 1;
    -+
    -+    We've hardcoded review and Special here, but as with StatusChange, you
    -+    could pass a value from the Parameters to Pass field. You can access
    -+    this value by calling the Argument method.
    -+
    -+        my $arg = $self->Argument;
    -+
    -+    Using passed arguments can make your conditions and actions more general
    -+    and potentially reusable.
    -+
    -+    Once the file is created, return to the RT web UI and create a new
    -+    condition, possibly by editing On Review Needed and clicking Copy
    -+    Condition. You can name it Special Review Needed and set the Condition
    -+    Module to SpecialReviewNeeded.
    -+
    -+  Custom Actions
    -+    Once you have the correct condition you can now think about the action.
    -+    You want to send email to a group of people, so to start you look at
    -+    some of the existing actions on the action display page at Admin >
    -+    Global > Actions (in RT 4.0, Tools > Global > Actions). You find Notify
    -+    AdminCcs, which might be close. Taking a quick look you see it has a
    -+    Name and Description, like conditions, and the module it calls is
    -+    Notify, which can be found at /opt/rt4/lib/RT/Action/Notify.pm.
    -+
    -+    The Parameter to Pass is AdminCc, and if you look at other notification
    -+    actions you'll see many use Notify and just pass a different ticket
    -+    role.
    -+
    -+    Your reviewers aren't always AdminCcs on tickets, so you'd rather send a
    -+    notification to a group. You can create this new action using the
    -+    existing action module NotifyGroup. On the action list page, click
    -+    Create and add something like the following:
    -+
    -+        Name               Notify Review Group
    -+        Description        Send notification to the review group
    -+        Action Module      NotifyGroup
    -+        Parameters to Pass Review Group
    -+
    -+    The 'Review Group' can be whatever your group name is. Then you can
    -+    build a template with some custom ticket information for reviewers and
    -+    set up a new scrip to send email to the review group whenever a ticket
    -+    status is set to review.
    -+
    -+  Custom Action Modules
    -+    As part of the request to add a condition to check for the 'Special'
    -+    custom field, we now want to route these special requests to the person
    -+    who handles them. This extra bit of functionality will require a module,
    -+    maybe called SetOwner. Create the new file in:
    -+
    -+        /local/lib/RT/Action/SetOwner.pm
    -+
    -+    The base action code looks like this:
    -+
    -+        package RT::Action::SetOwner;
    -+
    -+        use strict;
    -+        use warnings;
    -+        use base 'RT::Action';
    -+
    -+        sub Prepare {
    -+            my $self = shift;
    -+
    -+            # Your code here
    -+
    -+            return 1; # True if Commit should run, false if not
    -+        }
    -+
    -+        sub Commit {
    -+            my $self = shift;
    -+
    -+            # Your code here
    -+
    -+            return 1; # True if action was successful
    -+        }
    -+
    -+        1; # Don't forget module needs this
    -+
    -+    Actions have two methods you can override. The Prepare method provides
    -+    you with a chance to make sure the action should actually run. If
    -+    Prepare returns false, Commit will not run. You'll typically handle this
    -+    in your condition, in which case you can just omit Prepare from your
    -+    action. However, when you have a condition that covers a common general
    -+    case, but you want to check one extra criteria for a particular action,
    -+    the Prepare method can be helpful. In our example, you might choose to
    -+    keep just the On Review Needed condition and add the check for the
    -+    'Special' custom field to the Prepare method.
    -+
    -+    Commit is where you do the actual work of the action. It should return
    -+    true on success. On failure, you can use RT::Logger to write errors or
    -+    debugging information to RTs logs so you can track down the problem.
    -+
    -+    In actions, $self gives you access to the transaction and ticket
    -+    objects, just like conditions, via:
    -+
    -+        $self->TransactionObj
    -+        $self->TicketObj
    -+
    -+    For our SetOwner action, we don't need Prepare and can add the following
    -+    to Commit:
    -+
    -+        my $user = RT::User->new(RT->SystemUser);
    -+        my ($ret, $msg) = $user->Load($self->Argument);
    -+        RT::Logger->error('Unable to load user: '
    -+                           . $self->Argument . " $msg") unless $ret;
    -+
    -+        $self->TicketObj->SetOwner($user->Id);
    -+        return 1;
    -+
    -+    The Argument method returns the value set for Parameters to Pass in the
    -+    action configuration. This example expects the argument to be the
    -+    username of an RT user.
    -+
    -+    Now you can create the new action in RT. Go to the action page, click
    -+    Create, and enter the following:
    -+
    -+        Name               Set Owner
    -+        Description        Set owner
    -+        Action Module      SetOwner
    -+        Parameters to Pass reviewer_username
    -+
    -+    Click save and the new action will be available when creating scrips.
    -+
    -+    Note that actions you perform in scrips can themselves create new
    -+    transactions, as is the case with SetOwner. When this action runs, the
    -+    set owner transaction will fire the default On Owner Change Notify Owner
    -+    scrip, if it is enabled.
    -+
    -+ADDITIONAL INFORMATION
    -+    When writing actions and conditions, it's helpful to look at the actions
    -+    and conditions provided with RT. You can find more information about the
    -+    methods available from ticket and transaction objects in your RT
    -+    distribution and on the "Best Practical website"
    -+    <http://docs.bestpractical.com>.
    -+
    -+AUTHOR
    -+    Best Practical Solutions, LLC <modules at bestpractical.com>
    -+
    -+BUGS
    -+    All bugs should be reported via email to
    -+
    -+        L<bug-RT-Extension-AdminConditionsAndActions at rt.cpan.org|mailto:bug-RT-Extension-AdminConditionsAndActions at rt.cpan.org>
    -+
    -+    or via the web at
    -+
    -+        L<rt.cpan.org|http://rt.cpan.org/Public/Dist/Display.html?Name=RT-Extension-AdminConditionsAndActions>.
    -+
    -+LICENSE AND COPYRIGHT
    -+    This software is Copyright (c) 2014 by Best Practical Solutions
    -+
    -+    This is free software, licensed under:
    -+
    -+      The GNU General Public License, Version 2, June 1991
    -+
    ++=head1 Scrip Conditions & Actions
    ++
    ++The core building blocks of scrips in RT are the conditions and actions
    ++you select when configuring the scrip. A condition defines the criteria
    ++for an action to run in the context of the current transaction. The
    ++result is true or false: if true, the condition is satisfied and the
    ++action runs, if false, the action is skipped. Actions define something
    ++to be done when a condition is true and they can be anything you
    ++can capture in code, either changing things in RT or calling out to
    ++other systems, DBs, or APIs.
    ++
    ++You can view all of the scrips that come standard with RT
    ++by going to Tools > Global > Scrips (RT 4.0) or Admin >
    ++Global > Scrips (RT 4.2). In the scrips list you'll see each has a
    ++condition and an action and these are provided with the initial RT
    ++installation. You might also see additional conditions and actions added
    ++by extensions or through a local customization.
    ++
    ++This extension provides a web UI to allow you to easily register your
    ++own conditions and actions in RT, making it easier than ever to customize
    ++RT for your specific needs.
    ++
    ++=head2 User Defined Conditions and Actions
    ++
    ++The simplest way to add a custom condition or action is to create a new
    ++scrip and select "User Defined" as the Condition or Action. You can then
    ++put your custom code right in the "User Defined" boxes on the bottom of
    ++the scrip modification page.
    ++
    ++However, you might prefer writing your condition or action in a module
    ++with the code in a file. This allows you to track it in version control
    ++and call it from other places like C<rt-crontool>. The following sections
    ++describe how to create these modules.
    ++
    ++=head2 Custom Conditions
    ++
    ++Let's assume you have a custom lifecycle with a status
    ++called 'review' and you want an 'On Review Needed' condition so you can
    ++trigger actions when a ticket is put in review status. You notice RT
    ++already has 'On Resolve' and other similar conditions, so you look at
    ++the configuration at Admin > Global > Conditions and click on 'On Resolve'
    ++(in RT 4.0, select Tools > Global > Conditions.)
    ++
    ++The condition has a Name, which is displayed in the Condition dropdown when
    ++you create a scrip, and a Description to identify it. The Condition Module is
    ++the RT module that executes the condition, in this case C<StatusChange>. You
    ++can find the code in C</opt/rt4/lib/RT/Condition/StatusChange.pm> and view
    ++the documentation on the Best Practical L<"documentation site"|
    ++http://bestpractical.com/docs/rt/latest/RT/Condition/StatusChange.html>.
    ++(Confirm your RT version when checking the documentation.)
    ++
    ++Parameters to Pass shows the actual parameter that is passed to the module
    ++when this condition is executed. When you look at the module documentation
    ++it makes sense when you see that C<StatusChange> accepts a valid status and
    ++returns true if the transaction is setting the status to the provided value.
    ++Finally, Applicable Transaction Types lists the transactions for which this
    ++condition will run, and in this case it's Status transactions.
    ++
    ++This is really close to what we might need for our 'On Review Needed' so
    ++you can click the Copy Condition button to copy the current condition. On
    ++the new condition page, you can update the Name and Description and set
    ++the Parameters to Pass to 'review'. Then click save and you have your new
    ++condition. You can now create a new scrip and select it from the Condition
    ++dropdown.
    ++
    ++=head2 Custom Condition Module
    ++
    ++Now assume we have an additional requirement to check if a custom field value
    ++'Special' is selected when we check the review status. For this one
    ++we'll need to write some code. To start, create a new file for your new
    ++SpecialReviewNeeded module here:
    ++
    ++    /opt/rt4/local/lib/RT/Condition/SpecialReviewNeeded.pm
    ++
    ++Creating it in the C<local> directory will keep it safe when you apply
    ++RT upgrades in the future.
    ++
    ++The basics of a condition module are as follows:
    ++
    ++    package RT::Condition::SpecialReviewNeeded;
    ++
    ++    use strict;
    ++    use warnings;
    ++    use base 'RT::Condition';
    ++
    ++    sub IsApplicable {
    ++        my $self = shift;
    ++
    ++        # Your code here
    ++
    ++        return 1; # True if condition is true, false if not
    ++    }
    ++
    ++    1; # Don't forget module needs this
    ++
    ++C<IsApplicable> is the method you will override from the C<RT::Condition>
    ++base class. The return value of this method, true or false, determines
    ++whether the condition passes or not.
    ++
    ++C<$self> gives you access to the ticket object and transaction object via:
    ++
    ++    $self->TransactionObj
    ++    $self->TicketObj
    ++
    ++These are your main hooks into the current ticket and transaction.
    ++
    ++To check review status and the custom field value, we might add something
    ++like this:
    ++
    ++    # Setting status to review?
    ++    return 0 unless $self->TransactionObj->Type eq 'Status'
    ++        and $self->TransactionObj->NewValue eq 'review';
    ++
    ++    # Is 'Special' set to Yes?
    ++    return 0 unless $self->TicketObj->FirstCustomFieldValue('Special') eq 'Yes';
    ++
    ++    return 1;
    ++
    ++We've hardcoded C<review> and C<Special> here, but as with C<StatusChange>,
    ++you could pass a value from the Parameters to Pass field. You can access this
    ++value by calling the C<Argument> method.
    ++
    ++    my $arg = $self->Argument;
    ++
    ++Using passed arguments can make your conditions and actions more general
    ++and potentially reusable.
    ++
    ++Once the file is created, return to the RT web UI and create a new condition,
    ++possibly by editing On Review Needed and clicking Copy Condition.
    ++You can name it Special Review Needed and set the Condition Module to
    ++SpecialReviewNeeded.
    ++
    ++=head2 Custom Actions
    ++
    ++Once you have the correct condition you can now think about the action. You
    ++want to send email to a group of people, so to start you look at some of the
    ++existing actions on the action display page at Admin > Global > Actions (in RT 4.0,
    ++Tools > Global > Actions). You find Notify AdminCcs, which might be close. Taking
    ++a quick look you see it has a Name and Description, like conditions, and
    ++the module it calls is C<Notify>, which can be found at
    ++C</opt/rt4/lib/RT/Action/Notify.pm>.
    ++
    ++The Parameter to Pass is AdminCc, and if you look at other notification
    ++actions you'll see many use Notify and just pass a different ticket role.
    ++
    ++Your reviewers aren't always AdminCcs on tickets, so you'd rather
    ++send a notification to a group. You can create this new action using the
    ++existing action module C<NotifyGroup>. On the action list page, click Create
    ++and add something like the following:
    ++
    ++    Name               Notify Review Group
    ++    Description        Send notification to the review group
    ++    Action Module      NotifyGroup
    ++    Parameters to Pass Review Group
    ++
    ++The 'Review Group' can be whatever your group name is. Then you can build a
    ++template with some custom ticket information for reviewers and set up a new
    ++scrip to send email to the review group whenever a ticket status is set to
    ++review.
    ++
    ++=head2 Custom Action Modules
    ++
    ++As part of the request to add a condition to check for the 'Special' custom
    ++field, we now want to route these special requests to the person who handles
    ++them. This extra bit of functionality will require a module, maybe called
    ++C<SetOwner>. Create the new file in:
    ++
    ++    /local/lib/RT/Action/SetOwner.pm
    ++
    ++The base action code looks like this:
    ++
    ++    package RT::Action::SetOwner;
    ++
    ++    use strict;
    ++    use warnings;
    ++    use base 'RT::Action';
    ++
    ++    sub Prepare {
    ++        my $self = shift;
    ++
    ++        # Your code here
    ++
    ++        return 1; # True if Commit should run, false if not
    ++    }
    ++
    ++    sub Commit {
    ++        my $self = shift;
    ++
    ++        # Your code here
    ++
    ++        return 1; # True if action was successful
    ++    }
    ++
    ++    1; # Don't forget module needs this
    ++
    ++Actions have two methods you can override. The C<Prepare> method provides
    ++you with a chance to make sure the action should actually run.
    ++If C<Prepare> returns false, C<Commit> will not run. You'll typically
    ++handle this in your condition, in which case you can just omit C<Prepare>
    ++from your action. However, when you have a condition that covers a common
    ++general case, but you want to check one extra criteria for a particular
    ++action, the C<Prepare> method can be helpful. In our example, you might
    ++choose to keep just the On Review Needed condition and add the check
    ++for the 'Special' custom field to the C<Prepare> method.
    ++
    ++C<Commit> is where you do the actual work of the action. It should
    ++return true on success. On failure, you can use C<RT::Logger> to
    ++write errors or debugging information to RTs logs so you can track
    ++down the problem.
    ++
    ++In actions, C<$self> gives you access to the transaction and ticket
    ++objects, just like conditions, via:
    ++
    ++    $self->TransactionObj
    ++    $self->TicketObj
    ++
    ++For our C<SetOwner> action, we don't need C<Prepare> and can add the
    ++following to C<Commit>:
    ++
    ++    my $user = RT::User->new(RT->SystemUser);
    ++    my ($ret, $msg) = $user->Load($self->Argument);
    ++    RT::Logger->error('Unable to load user: '
    ++                       . $self->Argument . " $msg") unless $ret;
    ++
    ++    $self->TicketObj->SetOwner($user->Id);
    ++    return 1;
    ++
    ++The C<Argument> method returns the value set for Parameters to
    ++Pass in the action configuration. This example expects the
    ++argument to be the username of an RT user.
    ++
    ++Now you can create the new action in RT. Go to the action page, click
    ++Create, and enter the following:
    ++
    ++    Name               Set Owner
    ++    Description        Set owner
    ++    Action Module      SetOwner
    ++    Parameters to Pass reviewer_username
    ++
    ++Click save and the new action will be available when creating scrips.
    ++
    ++Note that actions you perform in scrips can themselves create new
    ++transactions, as is the case with C<SetOwner>. When this action runs,
    ++the set owner transaction will fire the default On Owner Change Notify
    ++Owner scrip, if it is enabled.
    ++
    ++=head1 ADDITIONAL INFORMATION
    ++
    ++When writing actions and conditions, it's helpful to look at the actions
    ++and conditions provided with RT. You can find more information about
    ++the methods available from ticket and transaction objects in your RT
    ++distribution and on the
    ++L<"Best Practical website"|http://docs.bestpractical.com>.
     
     diff --git a/lib/RT/ScripAction.pm b/lib/RT/ScripAction.pm
     --- a/lib/RT/ScripAction.pm



More information about the rt-commit mailing list