X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=rt%2Flib%2FRT%2FTransaction.pm;h=ca491a6c7c9cee19a4d7bc66a84e1d0c537080de;hp=ee1f069b24ce8692967d645e9cd32518f03379dd;hb=ded0451e9582df33cae6099a2fb72b4ea25076cf;hpb=0ebeec96313dd7edfca340f01f8fbbbac1f4aa1d diff --git a/rt/lib/RT/Transaction.pm b/rt/lib/RT/Transaction.pm index ee1f069b2..ca491a6c7 100755 --- a/rt/lib/RT/Transaction.pm +++ b/rt/lib/RT/Transaction.pm @@ -1,783 +1,364 @@ -# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Transaction.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $ -# Copyright 1999-2001 Jesse Vincent -# Released under the terms of the GNU Public License +# BEGIN LICENSE BLOCK +# +# Copyright (c) 1996-2003 Jesse Vincent +# +# (Except where explictly superceded by other copyright notices) +# +# This work is made available to you under the terms of Version 2 of +# the GNU General Public License. A copy of that license should have +# been provided with this software, but in any event can be snarfed +# from www.gnu.org. +# +# This work is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# Unless otherwise specified, all modifications, corrections or +# extensions to this work which alter its source code become the +# property of Best Practical Solutions, LLC when submitted for +# inclusion in the work. +# +# +# END LICENSE BLOCK +# Autogenerated by DBIx::SearchBuilder factory (by ) +# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST. +# +# !! DO NOT EDIT THIS FILE !! +# + +use strict; + =head1 NAME - RT::Transaction - RT\'s transaction object +RT::Transaction + =head1 SYNOPSIS - use RT::Transaction; +=head1 DESCRIPTION +=head1 METHODS -=head1 DESCRIPTION +=cut +package RT::Transaction; +use RT::Record; +use RT::Ticket; -Each RT::Transaction describes an atomic change to a ticket object -or an update to an RT::Ticket object. -It can have arbitrary MIME attachments. +use vars qw( @ISA ); +@ISA= qw( RT::Record ); + +sub _Init { + my $self = shift; + + $self->Table('Transactions'); + $self->SUPER::_Init(@_); +} -=head1 METHODS -=begin testing -ok(require RT::TestHarness); -ok(require RT::Transaction); -=end testing + +=item Create PARAMHASH + +Create takes a hash of values and creates a row in the database: + + int(11) 'EffectiveTicket'. + int(11) 'Ticket'. + int(11) 'TimeTaken'. + varchar(20) 'Type'. + varchar(40) 'Field'. + varchar(255) 'OldValue'. + varchar(255) 'NewValue'. + varchar(100) 'Data'. =cut -package RT::Transaction; -use RT::Record; -@ISA= qw(RT::Record); - -use RT::Attachments; -# {{{ sub _Init -sub _Init { + +sub Create { my $self = shift; - $self->{'table'} = "Transactions"; - return ($self->SUPER::_Init(@_)); + my %args = ( + EffectiveTicket => '0', + Ticket => '0', + TimeTaken => '0', + Type => '', + Field => '', + OldValue => '', + NewValue => '', + Data => '', + + @_); + $self->SUPER::Create( + EffectiveTicket => $args{'EffectiveTicket'}, + Ticket => $args{'Ticket'}, + TimeTaken => $args{'TimeTaken'}, + Type => $args{'Type'}, + Field => $args{'Field'}, + OldValue => $args{'OldValue'}, + NewValue => $args{'NewValue'}, + Data => $args{'Data'}, +); } -# }}} -# {{{ sub Create -=head2 Create -Create a new transaction. +=item id -This routine should _never_ be called anything other Than RT::Ticket. It should not be called -from client code. Ever. Not ever. If you do this, we will hunt you down. and break your kneecaps. -Then the unpleasant stuff will start. +Returns the current value of id. +(In the database, id is stored as int(11).) -TODO: Document what gets passed to this =cut -sub Create { - my $self = shift; - my %args = ( id => undef, - TimeTaken => 0, - Ticket => 0 , - Type => 'undefined', - Data => '', - Field => undef, - OldValue => undef, - NewValue => undef, - MIMEObj => undef, - ActivateScrips => 1, - @_ - ); - - #if we didn't specify a ticket, we need to bail - unless ( $args{'Ticket'} ) { - return(0, "RT::Transaction->Create couldn't, as you didn't specify a ticket id"); - } - - #lets create our transaction - my $id = $self->SUPER::Create(Ticket => $args{'Ticket'}, - TimeTaken => $args{'TimeTaken'}, - Type => $args{'Type'}, - Data => $args{'Data'}, - Field => $args{'Field'}, - OldValue => $args{'OldValue'}, - NewValue => $args{'NewValue'}, - Created => $args{'Created'} - ); - $self->Load($id); - $self->_Attach($args{'MIMEObj'}) - if defined $args{'MIMEObj'}; - - #Provide a way to turn off scrips if we need to - if ($args{'ActivateScrips'}) { - - #We're really going to need a non-acled ticket for the scrips to work - my $TicketAsSystem = RT::Ticket->new($RT::SystemUser); - $TicketAsSystem->Load($args{'Ticket'}) || - $RT::Logger->err("$self couldn't load ticket $args{'Ticket'}\n"); - - my $TransAsSystem = RT::Transaction->new($RT::SystemUser); - $TransAsSystem->Load($self->id) || - $RT::Logger->err("$self couldn't load a copy of itself as superuser\n"); - - # {{{ Deal with Scrips - - #Load a scripscopes object - use RT::Scrips; - my $PossibleScrips = RT::Scrips->new($RT::SystemUser); - - $PossibleScrips->LimitToQueue($TicketAsSystem->QueueObj->Id); #Limit it to $Ticket->QueueObj->Id - $PossibleScrips->LimitToGlobal(); # or to "global" - my $ConditionsAlias = $PossibleScrips->NewAlias('ScripConditions'); - - $PossibleScrips->Join(ALIAS1 => 'main', FIELD1 => 'ScripCondition', - ALIAS2 => $ConditionsAlias, FIELD2=> 'id'); - - - #We only want things where the scrip applies to this sort of transaction - $PossibleScrips->Limit(ALIAS=> $ConditionsAlias, - FIELD=>'ApplicableTransTypes', - OPERATOR => 'LIKE', - VALUE => $args{'Type'}, - ENTRYAGGREGATOR => 'OR', - ); - - # Or where the scrip applies to any transaction - $PossibleScrips->Limit(ALIAS=> $ConditionsAlias, - FIELD=>'ApplicableTransTypes', - OPERATOR => 'LIKE', - VALUE => "Any", - ENTRYAGGREGATOR => 'OR', - ); - - #Iterate through each script and check it's applicability. - - while (my $Scrip = $PossibleScrips->Next()) { - - #TODO: properly deal with errors raised in this scrip loop - - #$RT::Logger->debug("$self now dealing with ".$Scrip->Id. "\n"); - eval { - local $SIG{__DIE__} = sub { $RT::Logger->error($_[0])}; - - - #Load the scrip's Condition object - $Scrip->ConditionObj->LoadCondition(TicketObj => $TicketAsSystem, - TransactionObj => $TransAsSystem); - - - #If it's applicable, prepare and commit it - - $RT::Logger->debug ("$self: Checking condition ".$Scrip->ConditionObj->Name. "...\n"); - - if ( $Scrip->IsApplicable() ) { - - $RT::Logger->debug ("$self: Matches condition ".$Scrip->ConditionObj->Name. "...\n"); - #TODO: handle some errors here - - $Scrip->ActionObj->LoadAction(TicketObj => $TicketAsSystem, - TransactionObj => $TransAsSystem); - - - if ($Scrip->Prepare()) { - $RT::Logger->debug("$self: Prepared " . - $Scrip->ActionObj->Name . "\n"); - if ($Scrip->Commit()) { - $RT::Logger->debug("$self: Committed " . - $Scrip->ActionObj->Name . "\n"); - } - else { - $RT::Logger->info("$self: Failed to commit ". - $Scrip->ActionObj->Name . "\n"); - } - } - else { - $RT::Logger->info("$self: Failed to prepare " . - $Scrip->ActionObj->Name . "\n"); - } - - #We're done with it. lets clean up. - #TODO: something else isn't letting these get garbage collected. check em out. - $Scrip->ActionObj->DESTROY(); - $Scrip->ConditionObj->DESTROY; - } - - - else { - $RT::Logger->debug ("$self: Doesn't match condition ".$Scrip->ConditionObj->Name. "...\n"); - - # TODO: why doesn't this catch all the ScripObjs we create. - # and why do we explictly need to destroy them? - $Scrip->ConditionObj->DESTROY; - } - } - } - - # }}} - - } - - return ($id, "Transaction Created"); -} -# }}} +=item EffectiveTicket -# {{{ sub Delete +Returns the current value of EffectiveTicket. +(In the database, EffectiveTicket is stored as int(11).) -sub Delete { - my $self = shift; - return (0, 'Deleting this object could break referential integrity'); -} -# }}} -# {{{ Routines dealing with Attachments +=item SetEffectiveTicket VALUE -# {{{ sub Message -=head2 Message +Set EffectiveTicket to VALUE. +Returns (1, 'Status message') on success and (0, 'Error Message') on failure. +(In the database, EffectiveTicket will be stored as a int(11).) - Returns the RT::Attachments Object which contains the "top-level" object - attachment for this transaction =cut -sub Message { - my $self = shift; - - if (!defined ($self->{'message'}) ){ - - $self->{'message'} = new RT::Attachments($self->CurrentUser); - $self->{'message'}->Limit(FIELD => 'TransactionId', - VALUE => $self->Id); - - $self->{'message'}->ChildrenOf(0); - } - return($self->{'message'}); -} -# }}} +=item Ticket + +Returns the current value of Ticket. +(In the database, Ticket is stored as int(11).) + -# {{{ sub Content -=head2 Content PARAMHASH +=item SetTicket VALUE -If this transaction has attached mime objects, returns the first text/ part. -Otherwise, returns undef. -Takes a paramhash. If the $args{'Quote'} parameter is set, wraps this message -at $args{'Wrap'}. $args{'Wrap'} defaults to 70. +Set Ticket to VALUE. +Returns (1, 'Status message') on success and (0, 'Error Message') on failure. +(In the database, Ticket will be stored as a int(11).) =cut -sub Content { - my $self = shift; - my %args = ( Quote => 0, - Wrap => 70, - @_ ); - - my $content = undef; - - # If we don\'t have any content, return undef now. - unless ($self->Message->First) { - return (undef); - } - - # Get the set of toplevel attachments to this transaction. - my $MIMEObj = $self->Message->First(); - - # If it's a message or a plain part, just return the - # body. - if ($MIMEObj->ContentType() =~ '^(text|message)(/|$)') { - $content = $MIMEObj->Content(); - } - - # If it's a multipart object, first try returning the first - # text/plain part. - - elsif ($MIMEObj->ContentType() =~ '^multipart/') { - my $plain_parts = $MIMEObj->Children(); - $plain_parts->ContentType(VALUE => 'text/plain'); - - # If we actully found a part, return its content - if ($plain_parts->First && - $plain_parts->First->Content ne '') { - $content = $plain_parts->First->Content; - } - - # If that fails, return the first text/ or message/ part - # which has some content. - - else { - my $all_parts = $MIMEObj->Children(); - while (($content == undef) && - (my $part = $all_parts->Next)) { - if (($part->ContentType() =~ '^(text|message)(/|$)') and - ($part->Content())) { - $content = $part->Content; - } - } - } - - } - # If all else fails, return a message that we couldn't find - # any content - else { - $content = 'This transaction appears to have no content'; - } - - if ($args{'Quote'}) { - # Remove quoted signature. - $content =~ s/\n-- \n(.*)$//s; - - # What's the longest line like? - foreach (split (/\n/,$content)) { - $max=length if ( length > $max); - } - - if ($max>76) { - require Text::Wrapper; - my $wrapper=new Text::Wrapper - ( - columns => $args{'Wrap'}, - body_start => ($max > 70*3 ? ' ' : ''), - par_start => '' - ); - $content=$wrapper->wrap($content); - } - - $content =~ s/^/> /gm; - $content = '[' . $self->CreatorObj->Name() . ' - ' . $self->CreatedAsString() - . "]:\n\n" - . $content . "\n\n"; - - } - - return ($content); -} -# }}} -# {{{ sub Subject +=item TicketObj + +Returns the Ticket Object which has the id returned by Ticket -=head2 Subject -If this transaction has attached mime objects, returns the first one's subject -Otherwise, returns null - =cut -sub Subject { - my $self = shift; - if ($self->Message->First) { - return ($self->Message->First->Subject); - } - else { - return (undef); - } +sub TicketObj { + my $self = shift; + my $Ticket = RT::Ticket->new($self->CurrentUser); + $Ticket->Load($self->__Value('Ticket')); + return($Ticket); } -# }}} -# {{{ sub Attachments +=item TimeTaken + +Returns the current value of TimeTaken. +(In the database, TimeTaken is stored as int(11).) + -=head2 Attachments - Returns all the RT::Attachment objects which are attached -to this transaction. Takes an optional parameter, which is -a ContentType that Attachments should be restricted to. +=item SetTimeTaken VALUE + + +Set TimeTaken to VALUE. +Returns (1, 'Status message') on success and (0, 'Error Message') on failure. +(In the database, TimeTaken will be stored as a int(11).) + =cut -sub Attachments { - my $self = shift; - my $Types = ''; - $Types = shift if (@_); - - my $Attachments = new RT::Attachments($self->CurrentUser); - - #If it's a comment, return an empty object if they don't have the right to see it - if ($self->Type eq 'Comment') { - unless ($self->CurrentUserHasRight('ShowTicketComments')) { - return ($Attachments); - } - } - #if they ain't got rights to see, return an empty object - else { - unless ($self->CurrentUserHasRight('ShowTicket')) { - return ($Attachments); - } - } - - $Attachments->Limit(FIELD => 'TransactionId', - VALUE => $self->Id); - - # Get the attachments in the order they're put into - # the database. Arguably, we should be returning a tree - # of attachments, not a set...but no current app seems to need - # it. - - $Attachments->OrderBy(ALIAS => 'main', - FIELD => 'Id', - ORDER => 'asc'); - - if ($Types) { - $Attachments->ContentType( VALUE => "$Types", - OPERATOR => "LIKE"); - } - - - return($Attachments); - -} +=item Type -# }}} +Returns the current value of Type. +(In the database, Type is stored as varchar(20).) -# {{{ sub _Attach -=head2 _Attach -A private method used to attach a mime object to this transaction. +=item SetType VALUE + + +Set Type to VALUE. +Returns (1, 'Status message') on success and (0, 'Error Message') on failure. +(In the database, Type will be stored as a varchar(20).) + =cut -sub _Attach { - my $self = shift; - my $MIMEObject = shift; - - if (!defined($MIMEObject)) { - $RT::Logger->error("$self _Attach: We can't attach a mime object if you don't give us one.\n"); - return(0, "$self: no attachment specified"); - } - - - use RT::Attachment; - my $Attachment = new RT::Attachment ($self->CurrentUser); - $Attachment->Create(TransactionId => $self->Id, - Attachment => $MIMEObject); - return ($Attachment, "Attachment created"); - -} -# }}} +=item Field -# }}} +Returns the current value of Field. +(In the database, Field is stored as varchar(40).) -# {{{ Routines dealing with Transaction Attributes -# {{{ sub TicketObj -=head2 TicketObj +=item SetField VALUE + + +Set Field to VALUE. +Returns (1, 'Status message') on success and (0, 'Error Message') on failure. +(In the database, Field will be stored as a varchar(40).) -Returns this transaction's ticket object. =cut -sub TicketObj { - my $self = shift; - if (! exists $self->{'TicketObj'}) { - $self->{'TicketObj'} = new RT::Ticket($self->CurrentUser); - $self->{'TicketObj'}->Load($self->Ticket); - } - - return $self->{'TicketObj'}; -} -# }}} -# {{{ sub Description +=item OldValue + +Returns the current value of OldValue. +(In the database, OldValue is stored as varchar(255).) + + + +=item SetOldValue VALUE + -=head2 Description +Set OldValue to VALUE. +Returns (1, 'Status message') on success and (0, 'Error Message') on failure. +(In the database, OldValue will be stored as a varchar(255).) -Returns a text string which describes this transaction =cut -sub Description { - my $self = shift; +=item NewValue + +Returns the current value of NewValue. +(In the database, NewValue is stored as varchar(255).) - #Check those ACLs - #If it's a comment, we need to be extra special careful - if ($self->__Value('Type') eq 'Comment') { - unless ($self->CurrentUserHasRight('ShowTicketComments')) { - return (0, "Permission Denied"); - } - } - - #if they ain't got rights to see, don't let em - else { - unless ($self->CurrentUserHasRight('ShowTicket')) { - return (0, "Permission Denied"); - } - } - - if (!defined($self->Type)) { - return("No transaction type specified"); - } - - return ($self->BriefDescription . " by " . $self->CreatorObj->Name); -} -# }}} -# {{{ sub BriefDescription +=item SetNewValue VALUE -=head2 BriefDescription -Returns a text string which briefly describes this transaction +Set NewValue to VALUE. +Returns (1, 'Status message') on success and (0, 'Error Message') on failure. +(In the database, NewValue will be stored as a varchar(255).) + =cut -sub BriefDescription { - my $self = shift; +=item Data - #Check those ACLs - #If it's a comment, we need to be extra special careful - if ($self->__Value('Type') eq 'Comment') { - unless ($self->CurrentUserHasRight('ShowTicketComments')) { - return (0, "Permission Denied"); - } - } - - #if they ain't got rights to see, don't let em - else { - unless ($self->CurrentUserHasRight('ShowTicket')) { - return (0, "Permission Denied"); - } - } - - if (!defined($self->Type)) { - return("No transaction type specified"); - } - - if ($self->Type eq 'Create'){ - return("Ticket created"); - } - elsif ($self->Type =~ /Status/) { - if ($self->Field eq 'Status') { - if ($self->NewValue eq 'dead') { - return ("Ticket killed"); - } - else { - return( "Status changed from ". $self->OldValue . - " to ". $self->NewValue); - - } - } - # Generic: - return ($self->Field." changed from ".($self->OldValue||"(empty value)"). - " to ".$self->NewValue ); - } - - if ($self->Type eq 'Correspond') { - return("Correspondence added"); - } - - elsif ($self->Type eq 'Comment') { - return( "Comments added"); - } - - elsif ($self->Type eq 'Keyword') { - - my $field = 'Keyword'; - - if ($self->Field) { - my $keywordsel = new RT::KeywordSelect ($self->CurrentUser); - $keywordsel->Load($self->Field); - $field = $keywordsel->Name(); - } - - if ($self->OldValue eq '') { - return ($field." ".$self->NewValue." added"); - } - elsif ($self->NewValue eq '') { - return ($field." ".$self->OldValue." deleted"); - - } - else { - return ($field." ".$self->OldValue . " changed to ". - $self->NewValue); - } - } - - elsif ($self->Type eq 'Untake'){ - return( "Untaken"); - } - - elsif ($self->Type eq "Take") { - return( "Taken"); - } - - elsif ($self->Type eq "Force") { - my $Old = RT::User->new($self->CurrentUser); - $Old->Load($self->OldValue); - my $New = RT::User->new($self->CurrentUser); - $New->Load($self->NewValue); - return "Owner forcibly changed from ".$Old->Name . " to ". $New->Name; - } - elsif ($self->Type eq "Steal") { - my $Old = RT::User->new($self->CurrentUser); - $Old->Load($self->OldValue); - return "Stolen from ".$Old->Name; - } - - elsif ($self->Type eq "Give") { - my $New = RT::User->new($self->CurrentUser); - $New->Load($self->NewValue); - return( "Given to ".$New->Name); - } - - elsif ($self->Type eq 'AddWatcher'){ - return( $self->Field." ". $self->NewValue ." added"); - } - - elsif ($self->Type eq 'DelWatcher'){ - return( $self->Field." ".$self->OldValue ." deleted"); - } - - elsif ($self->Type eq 'Subject') { - return( "Subject changed to ".$self->Data); - } - elsif ($self->Type eq 'Told') { - return( "User notified"); - } - - elsif ($self->Type eq 'AddLink') { - return ($self->Data); - } - elsif ($self->Type eq 'DeleteLink') { - return ($self->Data); - } - elsif ($self->Type eq 'Set') { - if ($self->Field eq 'Queue') { - my $q1 = new RT::Queue($self->CurrentUser); - $q1->Load($self->OldValue); - my $q2 = new RT::Queue($self->CurrentUser); - $q2->Load($self->NewValue); - return ($self->Field . " changed from " . $q1->Name . " to ". - $q2->Name); - } - - # Write the date/time change at local time: - elsif ($self->Field =~ /Due|Starts|Started|Told/) { - my $t1 = new RT::Date($self->CurrentUser); - $t1->Set(Format => 'ISO', Value => $self->NewValue); - my $t2 = new RT::Date($self->CurrentUser); - $t2->Set(Format => 'ISO', Value => $self->OldValue); - return ($self->Field . " changed from " . $t2->AsString . - " to ".$t1->AsString); - } - else { - return ($self->Field . " changed from " . $self->OldValue . - " to ".$self->NewValue); - } - } - elsif ($self->Type eq 'PurgeTransaction') { - return ("Transaction ".$self->Data. " purged"); - } - else { - return ("Default: ". $self->Type ."/". $self->Field . - " changed from " . $self->OldValue . - " to ".$self->NewValue); - - } -} +Returns the current value of Data. +(In the database, Data is stored as varchar(100).) -# }}} -# {{{ Utility methods -# {{{ sub IsInbound +=item SetData VALUE -=head2 IsInbound -Returns true if the creator of the transaction is a requestor of the ticket. -Returns false otherwise +Set Data to VALUE. +Returns (1, 'Status message') on success and (0, 'Error Message') on failure. +(In the database, Data will be stored as a varchar(100).) -=cut -sub IsInbound { - my $self=shift; - return ($self->TicketObj->IsRequestor($self->CreatorObj)); -} +=cut -# }}} - -# }}} - -# {{{ sub _Accessible - -sub _Accessible { - my $self = shift; - my %Cols = ( - TimeTaken => 'read', - Ticket => 'read/public', - Type=> 'read', - Field => 'read', - Data => 'read', - NewValue => 'read', - OldValue => 'read', - Creator => 'read/auto', - Created => 'read/auto', - ); - return $self->SUPER::_Accessible(@_, %Cols); -} -# }}} +=item Creator -# }}} +Returns the current value of Creator. +(In the database, Creator is stored as int(11).) -# {{{ sub _Set -sub _Set { - my $self = shift; - return(0, 'Transactions are immutable'); -} +=cut -# }}} -# {{{ sub _Value +=item Created -=head2 _Value +Returns the current value of Created. +(In the database, Created is stored as datetime.) -Takes the name of a table column. -Returns its value as a string, if the user passes an ACL check =cut -sub _Value { - my $self = shift; - my $field = shift; - - - #if the field is public, return it. - if ($self->_Accessible($field, 'public')) { - return($self->__Value($field)); - - } - #If it's a comment, we need to be extra special careful - if ($self->__Value('Type') eq 'Comment') { - unless ($self->CurrentUserHasRight('ShowTicketComments')) { - return (undef); - } - } - #if they ain't got rights to see, don't let em - else { - unless ($self->CurrentUserHasRight('ShowTicket')) { - return (undef); - } - } - - return($self->__Value($field)); - -} -# }}} +sub _ClassAccessible { + { + + id => + {read => 1, type => 'int(11)', default => ''}, + EffectiveTicket => + {read => 1, write => 1, type => 'int(11)', default => '0'}, + Ticket => + {read => 1, write => 1, type => 'int(11)', default => '0'}, + TimeTaken => + {read => 1, write => 1, type => 'int(11)', default => '0'}, + Type => + {read => 1, write => 1, type => 'varchar(20)', default => ''}, + Field => + {read => 1, write => 1, type => 'varchar(40)', default => ''}, + OldValue => + {read => 1, write => 1, type => 'varchar(255)', default => ''}, + NewValue => + {read => 1, write => 1, type => 'varchar(255)', default => ''}, + Data => + {read => 1, write => 1, type => 'varchar(100)', default => ''}, + Creator => + {read => 1, auto => 1, type => 'int(11)', default => '0'}, + Created => + {read => 1, auto => 1, type => 'datetime', default => ''}, -# {{{ sub CurrentUserHasRight + } +}; -=head2 CurrentUserHasRight RIGHT -Calls $self->CurrentUser->HasQueueRight for the right passed in here. -passed in here. + eval "require RT::Transaction_Overlay"; + if ($@ && $@ !~ qr{^Can't locate RT/Transaction_Overlay.pm}) { + die $@; + }; -=cut + eval "require RT::Transaction_Vendor"; + if ($@ && $@ !~ qr{^Can't locate RT/Transaction_Vendor.pm}) { + die $@; + }; -sub CurrentUserHasRight { - my $self = shift; - my $right = shift; - return ($self->CurrentUser->HasQueueRight(Right => "$right", - TicketObj => $self->TicketObj)); -} + eval "require RT::Transaction_Local"; + if ($@ && $@ !~ qr{^Can't locate RT/Transaction_Local.pm}) { + die $@; + }; + + + + +=head1 SEE ALSO + +This class allows "overlay" methods to be placed +into the following files _Overlay is for a System overlay by the original author, +_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations. + +These overlay files can contain new subs or subs to replace existing subs in this module. + +If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line + + no warnings qw(redefine); + +so that perl does not kick and scream when you redefine a subroutine or variable in your overlay. + +RT::Transaction_Overlay, RT::Transaction_Vendor, RT::Transaction_Local + +=cut -# }}} 1;