1 # BEGIN BPS TAGGED BLOCK {{{
5 # This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
6 # <sales@bestpractical.com>
8 # (Except where explicitly superseded by other copyright notices)
13 # This work is made available to you under the terms of Version 2 of
14 # the GNU General Public License. A copy of that license should have
15 # been provided with this software, but in any event can be snarfed
18 # This work is distributed in the hope that it will be useful, but
19 # WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 # General Public License for more details.
23 # You should have received a copy of the GNU General Public License
24 # along with this program; if not, write to the Free Software
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 # 02110-1301 or visit their web page on the internet at
27 # http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
30 # CONTRIBUTION SUBMISSION POLICY:
32 # (The following paragraph is not intended to limit the rights granted
33 # to you to modify and distribute this software under the terms of
34 # the GNU General Public License and is only of importance to you if
35 # you choose to contribute your changes and enhancements to the
36 # community by submitting them to Best Practical Solutions, LLC.)
38 # By intentionally submitting any modifications, corrections or
39 # derivatives to this work, or any other work intended for use with
40 # Request Tracker, to Best Practical Solutions, LLC, you confirm that
41 # you are the copyright holder for those contributions and you grant
42 # Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
43 # royalty-free, perpetual, license to use, copy, create derivative
44 # works based on those contributions, and sublicense and distribute
45 # those contributions and any derivatives thereof.
47 # END BPS TAGGED BLOCK }}}
51 RT::Scrip - an RT Scrip object
70 use base 'RT::Record';
74 use RT::ScripCondition;
85 Creates a new entry in the Scrips table. Takes a paramhash with:
91 ScripCondition => undef,
92 CustomPrepareCode => undef,
93 CustomCommitCode => undef,
94 CustomIsApplicableCode => undef,
99 Returns (retval, msg);
100 retval is 0 for failure or scrip id. msg is a textual description of what happened.
108 Template => undef, # name or id
109 ScripAction => 0, # name or id
110 ScripCondition => 0, # name or id
111 Stage => 'TransactionCreate',
112 Description => undef,
113 CustomPrepareCode => undef,
114 CustomCommitCode => undef,
115 CustomIsApplicableCode => undef,
119 if ($args{CustomPrepareCode} || $args{CustomCommitCode} || $args{CustomIsApplicableCode}) {
120 unless ( $self->CurrentUser->HasRight( Object => $RT::System,
121 Right => 'ExecuteCode' ) )
123 return ( 0, $self->loc('Permission Denied') );
127 unless ( $args{'Queue'} ) {
128 unless ( $self->CurrentUser->HasRight( Object => $RT::System,
129 Right => 'ModifyScrips' ) )
131 return ( 0, $self->loc('Permission Denied') );
133 $args{'Queue'} = 0; # avoid undef sneaking in
136 my $QueueObj = RT::Queue->new( $self->CurrentUser );
137 $QueueObj->Load( $args{'Queue'} );
138 unless ( $QueueObj->id ) {
139 return ( 0, $self->loc('Invalid queue') );
141 unless ( $QueueObj->CurrentUserHasRight('ModifyScrips') ) {
142 return ( 0, $self->loc('Permission Denied') );
144 $args{'Queue'} = $QueueObj->id;
147 #TODO +++ validate input
149 return ( 0, $self->loc("Action is mandatory argument") )
150 unless $args{'ScripAction'};
151 my $action = RT::ScripAction->new( $self->CurrentUser );
152 $action->Load( $args{'ScripAction'} );
153 return ( 0, $self->loc( "Action '[_1]' not found", $args{'ScripAction'} ) )
156 return ( 0, $self->loc("Template is mandatory argument") )
157 unless $args{'Template'};
158 my $template = RT::Template->new( $self->CurrentUser );
159 if ( $args{'Template'} =~ /\D/ ) {
160 $template->LoadByName( Name => $args{'Template'}, Queue => $args{'Queue'} );
161 return ( 0, $self->loc( "Global template '[_1]' not found", $args{'Template'} ) )
162 if !$template->Id && !$args{'Queue'};
163 return ( 0, $self->loc( "Global or queue specific template '[_1]' not found", $args{'Template'} ) )
166 $template->Load( $args{'Template'} );
167 return ( 0, $self->loc( "Template '[_1]' not found", $args{'Template'} ) )
168 unless $template->Id;
170 return (0, $self->loc( "Template '[_1]' is not global" ))
171 if !$args{'Queue'} && $template->Queue;
172 return (0, $self->loc( "Template '[_1]' is not global nor queue specific" ))
173 if $args{'Queue'} && $template->Queue && $template->Queue != $args{'Queue'};
176 return ( 0, $self->loc("Condition is mandatory argument") )
177 unless $args{'ScripCondition'};
178 my $condition = RT::ScripCondition->new( $self->CurrentUser );
179 $condition->Load( $args{'ScripCondition'} );
180 return ( 0, $self->loc( "Condition '[_1]' not found", $args{'ScripCondition'} ) )
181 unless $condition->Id;
183 if ( $args{'Stage'} eq 'Disabled' ) {
184 $RT::Logger->warning("Disabled Stage is deprecated");
185 $args{'Stage'} = 'TransactionCreate';
186 $args{'Disabled'} = 1;
188 $args{'Disabled'} ||= 0;
190 my ( $id, $msg ) = $self->SUPER::Create(
191 Template => $template->Name,
192 ScripCondition => $condition->id,
193 ScripAction => $action->Id,
194 Disabled => $args{'Disabled'},
195 Description => $args{'Description'},
196 CustomPrepareCode => $args{'CustomPrepareCode'},
197 CustomCommitCode => $args{'CustomCommitCode'},
198 CustomIsApplicableCode => $args{'CustomIsApplicableCode'},
200 return ( $id, $msg ) unless $id;
202 (my $status, $msg) = RT::ObjectScrip->new( $self->CurrentUser )->Add(
204 Stage => $args{'Stage'},
205 ObjectId => $args{'Queue'},
207 $RT::Logger->error( "Couldn't add scrip: $msg" ) unless $status;
209 return ( $id, $self->loc('Scrip Created') );
223 unless ( $self->CurrentUserHasRight('ModifyScrips') ) {
224 return ( 0, $self->loc('Permission Denied') );
227 RT::ObjectScrip->new( $self->CurrentUser )->DeleteAll( Scrip => $self );
229 return ( $self->SUPER::Delete(@_) );
232 sub IsGlobal { return shift->IsAdded(0) }
236 my $record = RT::ObjectScrip->new( $self->CurrentUser );
237 $record->LoadByCols( Scrip => $self->id, ObjectId => shift || 0 );
238 return undef unless $record->id;
244 my $record = RT::ObjectScrip->new( $self->CurrentUser );
245 $record->LoadByCols( Scrip => $self->id );
246 return $record->id ? 1 : 0;
251 return RT::ObjectScrip->new( $self->CurrentUser )
252 ->AddedTo( Scrip => $self );
257 return RT::ObjectScrip->new( $self->CurrentUser )
258 ->NotAddedTo( Scrip => $self );
263 Adds (applies) the current scrip to the provided queue (ObjectId).
265 Accepts a param hash of:
271 Queue name or id. 0 makes the scrip global.
275 Stage to run in. Valid stages are TransactionCreate or
276 TransactionBatch. Defaults to TransactionCreate. As of RT 4.2, Disabled
277 is no longer a stage.
281 Name of global or queue-specific template for the scrip. Use 'Blank' for
282 non-notification scrips.
286 Number indicating the relative order the scrip should run in.
290 Returns (val, message). If val is false, the message contains an error
297 my %args = @_%2? (ObjectId => @_) : (@_);
299 # Default Stage explicitly rather than in %args assignment to handle
300 # Stage coming in set to undef.
301 $args{'Stage'} //= 'TransactionCreate';
304 if ( $args{'ObjectId'} ) {
305 $queue = RT::Queue->new( $self->CurrentUser );
306 $queue->Load( $args{'ObjectId'} );
307 return (0, $self->loc('Invalid queue'))
310 $args{'ObjectId'} = $queue->id;
312 return ( 0, $self->loc('Permission Denied') )
313 unless $self->CurrentUser->PrincipalObj->HasRight(
314 Object => $queue || $RT::System, Right => 'ModifyScrips',
318 my $tname = $self->Template;
319 my $template = RT::Template->new( $self->CurrentUser );
320 $template->LoadByName( Queue => $queue? $queue->id : 0, Name => $tname );
321 unless ( $template->id ) {
323 return (0, $self->loc('No template [_1] in queue [_2] or global',
324 $tname, $queue->Name||$queue->id));
326 return (0, $self->loc('No global template [_1]', $tname));
330 my $rec = RT::ObjectScrip->new( $self->CurrentUser );
331 return $rec->Add( %args, Scrip => $self );
334 =head2 RemoveFromObject
336 Removes the current scrip to the provided queue (ObjectId).
338 Accepts a param hash of:
344 Queue name or id. 0 makes the scrip global.
348 Returns (val, message). If val is false, the message contains an error
353 sub RemoveFromObject {
355 my %args = @_%2? (ObjectId => @_) : (@_);
358 if ( $args{'ObjectId'} ) {
359 $queue = RT::Queue->new( $self->CurrentUser );
360 $queue->Load( $args{'ObjectId'} );
361 return (0, $self->loc('Invalid queue id'))
364 return ( 0, $self->loc('Permission Denied') )
365 unless $self->CurrentUser->PrincipalObj->HasRight(
366 Object => $queue || $RT::System, Right => 'ModifyScrips',
370 my $rec = RT::ObjectScrip->new( $self->CurrentUser );
371 $rec->LoadByCols( Scrip => $self->id, ObjectId => $args{'ObjectId'} );
372 return (0, $self->loc('Scrip is not added') ) unless $rec->id;
378 Retuns an RT::Action object with this Scrip's Action
385 unless ( defined $self->{'ScripActionObj'} ) {
386 require RT::ScripAction;
387 $self->{'ScripActionObj'} = RT::ScripAction->new( $self->CurrentUser );
388 $self->{'ScripActionObj'}->Load( $self->ScripAction );
390 return ( $self->{'ScripActionObj'} );
397 Retuns an L<RT::ScripCondition> object with this Scrip's IsApplicable
404 my $res = RT::ScripCondition->new( $self->CurrentUser );
405 $res->Load( $self->ScripCondition );
412 Loads scrip's condition and action modules.
419 $self->ConditionObj->LoadCondition;
420 $self->ActionObj->LoadAction;
426 Retuns an RT::Template object with this Scrip's Template
434 my $res = RT::Template->new( $self->CurrentUser );
435 $res->LoadByName( Queue => $queue, Name => $self->Template );
441 Takes TicketObj named argument and returns scrip's stage when
442 added to ticket's queue.
448 my %args = ( TicketObj => undef, @_ );
450 my $queue = $args{'TicketObj'}->Queue;
451 my $rec = RT::ObjectScrip->new( $self->CurrentUser );
452 $rec->LoadByCols( Scrip => $self->id, ObjectId => $queue );
453 return $rec->Stage if $rec->id;
455 $rec->LoadByCols( Scrip => $self->id, ObjectId => 0 );
456 return $rec->Stage if $rec->id;
461 =head2 FriendlyStage($Stage)
463 Helper function that returns a localized human-readable version of the
469 my ( $class, $stage ) = @_;
470 my $stage_i18n_lookup = {
471 TransactionCreate => 'Normal', # loc
472 TransactionBatch => 'Batch', # loc
473 TransactionBatchDisabled => 'Batch (disabled by config)', # loc
475 $stage = 'TransactionBatchDisabled'
476 if $stage eq 'TransactionBatch'
477 and not RT->Config->Get('UseTransactionBatch');
478 return $stage_i18n_lookup->{$stage};
481 =head2 Apply { TicketObj => undef, TransactionObj => undef}
483 This method instantiates the ScripCondition and ScripAction objects for a
484 single execution of this scrip. it then calls the IsApplicable method of the
486 If that succeeds, it calls the Prepare method of the
487 ScripAction. If that succeeds, it calls the Commit method of the ScripAction.
489 Usually, the ticket and transaction objects passed to this method
490 should be loaded by the SuperUser role
495 # XXX TODO : This code appears to be obsoleted in favor of similar code in Scrips->Apply.
496 # Why is this here? Is it still called?
500 my %args = ( TicketObj => undef,
501 TransactionObj => undef,
504 $RT::Logger->debug("Now applying scrip ".$self->Id . " for transaction ".$args{'TransactionObj'}->id);
506 my $ApplicableTransactionObj = $self->IsApplicable( TicketObj => $args{'TicketObj'},
507 TransactionObj => $args{'TransactionObj'} );
508 unless ( $ApplicableTransactionObj ) {
512 if ( $ApplicableTransactionObj->id != $args{'TransactionObj'}->id ) {
513 $RT::Logger->debug("Found an applicable transaction ".$ApplicableTransactionObj->Id . " in the same batch with transaction ".$args{'TransactionObj'}->id);
516 #If it's applicable, prepare and commit it
517 $RT::Logger->debug("Now preparing scrip ".$self->Id . " for transaction ".$ApplicableTransactionObj->id);
518 unless ( $self->Prepare( TicketObj => $args{'TicketObj'},
519 TransactionObj => $ApplicableTransactionObj )
524 $RT::Logger->debug("Now commiting scrip ".$self->Id . " for transaction ".$ApplicableTransactionObj->id);
525 unless ( $self->Commit( TicketObj => $args{'TicketObj'},
526 TransactionObj => $ApplicableTransactionObj)
531 $RT::Logger->debug("We actually finished scrip ".$self->Id . " for transaction ".$ApplicableTransactionObj->id);
540 Calls the Condition object's IsApplicable method
542 Upon success, returns the applicable Transaction object.
543 Otherwise, undef is returned.
545 If the Scrip is in the TransactionCreate Stage (the usual case), only test
546 the associated Transaction object to see if it is applicable.
548 For Scrips in the TransactionBatch Stage, test all Transaction objects
549 created during the Ticket object's lifetime, and returns the first one
556 my %args = ( TicketObj => undef,
557 TransactionObj => undef,
565 my $stage = $self->Stage( TicketObj => $args{'TicketObj'} );
568 "Scrip #". $self->id ." is not applied to"
569 ." queue #". $args{'TicketObj'}->Queue
573 elsif ( $stage eq 'TransactionCreate') {
574 # Only look at our current Transaction
575 @Transactions = ( $args{'TransactionObj'} );
577 elsif ( $stage eq 'TransactionBatch') {
578 # Look at all Transactions in this Batch
579 @Transactions = @{ $args{'TicketObj'}->TransactionBatch || [] };
582 $RT::Logger->error( "Unknown Scrip stage: '$stage'" );
585 my $ConditionObj = $self->ConditionObj;
586 foreach my $TransactionObj ( @Transactions ) {
587 # in TxnBatch stage we can select scrips that are not applicable to all txns
588 my $txn_type = $TransactionObj->Type;
589 next unless( $ConditionObj->ApplicableTransTypes =~ /(?:^|,)(?:Any|\Q$txn_type\E)(?:,|$)/i );
590 # Load the scrip's Condition object
591 $ConditionObj->LoadCondition(
593 TicketObj => $args{'TicketObj'},
594 TransactionObj => $TransactionObj,
597 if ( $ConditionObj->IsApplicable() ) {
598 # We found an application Transaction -- return it
599 $return = $TransactionObj;
606 $RT::Logger->error( "Scrip IsApplicable " . $self->Id . " died. - " . $@ );
618 Calls the action object's prepare method
624 my %args = ( TicketObj => undef,
625 TransactionObj => undef,
630 $self->ActionObj->LoadAction(
632 TicketObj => $args{'TicketObj'},
633 TransactionObj => $args{'TransactionObj'},
634 TemplateObj => $self->TemplateObj( $args{'TicketObj'}->Queue ),
637 $return = $self->ActionObj->Prepare();
640 $RT::Logger->error( "Scrip Prepare " . $self->Id . " died. - " . $@ );
652 Calls the action object's commit method
658 my %args = ( TicketObj => undef,
659 TransactionObj => undef,
664 $return = $self->ActionObj->Commit();
667 #Searchbuilder caching isn't perfectly coherent. got to reload the ticket object, since it
669 $args{'TicketObj'}->Load( $args{'TicketObj'}->Id );
672 $RT::Logger->error( "Scrip Commit " . $self->Id . " died. - " . $@ );
676 # Not destroying or weakening hte Action and Condition here could cause a
686 # does an acl check and then passes off the call
695 unless ( $self->CurrentUserHasRight('ModifyScrips') ) {
696 $RT::Logger->debug( "CurrentUser can't modify Scrips" );
697 return ( 0, $self->loc('Permission Denied') );
701 if (exists $args{Value}) {
702 if ($args{Field} eq 'CustomIsApplicableCode' || $args{Field} eq 'CustomPrepareCode' || $args{Field} eq 'CustomCommitCode') {
703 unless ( $self->CurrentUser->HasRight( Object => $RT::System,
704 Right => 'ExecuteCode' ) ) {
705 return ( 0, $self->loc('Permission Denied') );
708 elsif ($args{Field} eq 'Queue') {
710 # moving to another queue
711 my $queue = RT::Queue->new( $self->CurrentUser );
712 $queue->Load($args{Value});
713 unless ($queue->Id and $queue->CurrentUserHasRight('ModifyScrips')) {
714 return ( 0, $self->loc('Permission Denied') );
718 unless ($self->CurrentUser->HasRight( Object => RT->System, Right => 'ModifyScrips' )) {
719 return ( 0, $self->loc('Permission Denied') );
723 elsif ($args{Field} eq 'Template') {
724 my $template = RT::Template->new( $self->CurrentUser );
725 $template->Load($args{Value});
726 unless ($template->Id and $template->CurrentUserCanRead) {
727 return ( 0, $self->loc('Permission Denied') );
732 return $self->SUPER::_Set(@_);
736 # does an acl check and then passes off the call
740 return unless $self->CurrentUserHasRight('ShowScrips');
742 return $self->__Value(@_);
745 =head2 ACLEquivalenceObjects
747 Having rights on any of the queues the scrip applies to is equivalent to
748 having rights on the scrip.
752 sub ACLEquivalenceObjects {
754 return unless $self->id;
755 return @{ $self->AddedTo->ItemsArrayRef };
762 This routine compile-checks the custom prepare, commit, and is-applicable code
763 to see if they are syntactically valid Perl. We eval them in a codeblock to
764 avoid actually executing the code.
766 If one of the fields has a compile error, only the first is reported.
768 Returns an (ok, message) pair.
775 for my $method (qw/CustomPrepareCode CustomCommitCode CustomIsApplicableCode/) {
776 my $code = $self->$method;
777 next if !defined($code);
781 eval "sub { $code \n }";
786 return (0, $self->loc("Couldn't compile [_1] codeblock '[_2]': [_3]", $method, $code, $error));
791 =head2 SetScripAction
799 return ( 0, $self->loc("Action is mandatory argument") ) unless $value;
801 require RT::ScripAction;
802 my $action = RT::ScripAction->new( $self->CurrentUser );
803 $action->Load($value);
804 return ( 0, $self->loc( "Action '[_1]' not found", $value ) )
807 return $self->_Set( Field => 'ScripAction', Value => $action->Id );
810 =head2 SetScripCondition
814 sub SetScripCondition {
818 return ( 0, $self->loc("Condition is mandatory argument") )
821 require RT::ScripCondition;
822 my $condition = RT::ScripCondition->new( $self->CurrentUser );
823 $condition->Load($value);
825 return ( 0, $self->loc( "Condition '[_1]' not found", $value ) )
826 unless $condition->Id;
828 return $self->_Set( Field => 'ScripCondition', Value => $condition->Id );
839 return ( 0, $self->loc("Template is mandatory argument") ) unless $value;
841 require RT::Template;
842 my $template = RT::Template->new( $self->CurrentUser );
843 $template->Load($value);
844 return ( 0, $self->loc( "Template '[_1]' not found", $value ) )
845 unless $template->Id;
847 return $self->_Set( Field => 'Template', Value => $template->Name );
859 Returns the current value of id.
860 (In the database, id is stored as int(11).)
868 Returns the current value of Description.
869 (In the database, Description is stored as varchar(255).)
873 =head2 SetDescription VALUE
876 Set Description to VALUE.
877 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
878 (In the database, Description will be stored as a varchar(255).)
884 =head2 ScripCondition
886 Returns the current value of ScripCondition.
887 (In the database, ScripCondition is stored as int(11).)
891 =head2 SetScripCondition VALUE
894 Set ScripCondition to VALUE.
895 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
896 (In the database, ScripCondition will be stored as a int(11).)
902 =head2 ScripConditionObj
904 Returns the ScripCondition Object which has the id returned by ScripCondition
909 sub ScripConditionObj {
911 my $ScripCondition = RT::ScripCondition->new($self->CurrentUser);
912 $ScripCondition->Load($self->__Value('ScripCondition'));
913 return($ScripCondition);
918 Returns the current value of ScripAction.
919 (In the database, ScripAction is stored as int(11).)
923 =head2 SetScripAction VALUE
926 Set ScripAction to VALUE.
927 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
928 (In the database, ScripAction will be stored as a int(11).)
934 =head2 ScripActionObj
936 Returns the ScripAction Object which has the id returned by ScripAction
943 my $ScripAction = RT::ScripAction->new($self->CurrentUser);
944 $ScripAction->Load($self->__Value('ScripAction'));
945 return($ScripAction);
948 =head2 CustomIsApplicableCode
950 Returns the current value of CustomIsApplicableCode.
951 (In the database, CustomIsApplicableCode is stored as text.)
955 =head2 SetCustomIsApplicableCode VALUE
958 Set CustomIsApplicableCode to VALUE.
959 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
960 (In the database, CustomIsApplicableCode will be stored as a text.)
966 =head2 CustomPrepareCode
968 Returns the current value of CustomPrepareCode.
969 (In the database, CustomPrepareCode is stored as text.)
973 =head2 SetCustomPrepareCode VALUE
976 Set CustomPrepareCode to VALUE.
977 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
978 (In the database, CustomPrepareCode will be stored as a text.)
984 =head2 CustomCommitCode
986 Returns the current value of CustomCommitCode.
987 (In the database, CustomCommitCode is stored as text.)
991 =head2 SetCustomCommitCode VALUE
994 Set CustomCommitCode to VALUE.
995 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
996 (In the database, CustomCommitCode will be stored as a text.)
1004 Returns the current value of Disabled.
1005 (In the database, Disabled is stored as smallint(6).)
1009 =head2 SetDisabled VALUE
1012 Set Disabled to VALUE.
1013 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
1014 (In the database, Disabled will be stored as a smallint(6).)
1022 Returns the current value of Template.
1023 (In the database, Template is stored as varchar(200).)
1027 =head2 SetTemplate VALUE
1030 Set Template to VALUE.
1031 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
1032 (In the database, Template will be stored as a varchar(200).)
1040 Returns the current value of Creator.
1041 (In the database, Creator is stored as int(11).)
1049 Returns the current value of Created.
1050 (In the database, Created is stored as datetime.)
1056 =head2 LastUpdatedBy
1058 Returns the current value of LastUpdatedBy.
1059 (In the database, LastUpdatedBy is stored as int(11).)
1067 Returns the current value of LastUpdated.
1068 (In the database, LastUpdated is stored as datetime.)
1075 sub _CoreAccessible {
1079 {read => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => ''},
1081 {read => 1, write => 1, sql_type => 12, length => 255, is_blob => 0, is_numeric => 0, type => 'varchar(255)', default => ''},
1083 {read => 1, write => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => '0'},
1085 {read => 1, write => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => '0'},
1086 CustomIsApplicableCode =>
1087 {read => 1, write => 1, sql_type => -4, length => 0, is_blob => 1, is_numeric => 0, type => 'text', default => ''},
1088 CustomPrepareCode =>
1089 {read => 1, write => 1, sql_type => -4, length => 0, is_blob => 1, is_numeric => 0, type => 'text', default => ''},
1091 {read => 1, write => 1, sql_type => -4, length => 0, is_blob => 1, is_numeric => 0, type => 'text', default => ''},
1093 {read => 1, write => 1, sql_type => 5, length => 6, is_blob => 0, is_numeric => 1, type => 'smallint(6)', default => '0'},
1095 {read => 1, write => 1, sql_type => 12, length => 200, is_blob => 0, is_numeric => 0, type => 'varchar(200)', default => 'Blank'},
1097 {read => 1, auto => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => '0'},
1099 {read => 1, auto => 1, sql_type => 11, length => 0, is_blob => 0, is_numeric => 0, type => 'datetime', default => ''},
1101 {read => 1, auto => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => '0'},
1103 {read => 1, auto => 1, sql_type => 11, length => 0, is_blob => 0, is_numeric => 0, type => 'datetime', default => ''},
1108 sub FindDependencies {
1110 my ($walker, $deps) = @_;
1112 $self->SUPER::FindDependencies($walker, $deps);
1114 my $applied = RT::ObjectScrips->new( $self->CurrentUser );
1115 $applied->LimitToScrip( $self->id );
1116 $deps->Add( in => $applied );
1118 $deps->Add( out => $self->ScripConditionObj );
1119 $deps->Add( out => $self->ScripActionObj );
1120 $deps->Add( out => $self->TemplateObj );
1127 Dependencies => undef,
1130 my $deps = $args{'Dependencies'};
1133 my $objs = RT::ObjectScrips->new( $self->CurrentUser );
1134 $objs->LimitToScrip( $self->Id );
1137 $deps->_PushDependencies(
1138 BaseObject => $self,
1139 Flags => RT::Shredder::Constants::DEPENDS_ON,
1140 TargetObjects => $list,
1141 Shredder => $args{'Shredder'}
1144 return $self->SUPER::__DependsOn( %args );
1150 my %store = $self->SUPER::Serialize(@_);
1152 # Store the string, not a reference to the object
1153 $store{Template} = $self->Template;
1158 RT::Base->_ImportOverlays();