summaryrefslogtreecommitdiff
path: root/rt/lib/RT/Transaction_Overlay.pm
diff options
context:
space:
mode:
Diffstat (limited to 'rt/lib/RT/Transaction_Overlay.pm')
-rw-r--r--rt/lib/RT/Transaction_Overlay.pm796
1 files changed, 0 insertions, 796 deletions
diff --git a/rt/lib/RT/Transaction_Overlay.pm b/rt/lib/RT/Transaction_Overlay.pm
deleted file mode 100644
index 9c9a2fd..0000000
--- a/rt/lib/RT/Transaction_Overlay.pm
+++ /dev/null
@@ -1,796 +0,0 @@
-# BEGIN LICENSE BLOCK
-#
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-#
-# (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
-=head1 NAME
-
- RT::Transaction - RT\'s transaction object
-
-=head1 SYNOPSIS
-
- use RT::Transaction;
-
-
-=head1 DESCRIPTION
-
-
-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.
-
-
-=head1 METHODS
-
-=begin testing
-
-ok(require RT::Transaction);
-
-=end testing
-
-=cut
-
-use strict;
-no warnings qw(redefine);
-
-use vars qw( %_BriefDescriptions );
-
-use RT::Attachments;
-
-# {{{ sub Create
-
-=head2 Create
-
-Create a new transaction.
-
-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.
-
-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, $self->loc( "Transaction->Create couldn't, as you didn't specify a ticket id"));
- }
-
-
-
- #lets create our transaction
- my %params = (Ticket => $args{'Ticket'},
- Type => $args{'Type'},
- Data => $args{'Data'},
- Field => $args{'Field'},
- OldValue => $args{'OldValue'},
- NewValue => $args{'NewValue'},
- Created => $args{'Created'}
- );
-
- # Parameters passed in during an import that we probably don't want to touch, otherwise
- foreach my $attr qw(id Creator Created LastUpdated TimeTaken LastUpdatedBy) {
- $params{$attr} = $args{$attr} if ($args{$attr});
- }
-
- my $id = $self->SUPER::Create(%params);
- $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'} ) {
- require RT::Scrips;
- RT::Scrips->new($RT::SystemUser)->Apply(
- Stage => 'TransactionCreate',
- Type => $args{'Type'},
- Ticket => $args{'Ticket'},
- Transaction => $self->id,
- );
- }
-
- return ( $id, $self->loc("Transaction Created") );
-}
-
-# }}}
-
-# {{{ sub Delete
-
-sub Delete {
- my $self = shift;
- return ( 0,
- $self->loc('Deleting this object could break referential integrity') );
-}
-
-# }}}
-
-# {{{ Routines dealing with Attachments
-
-# {{{ sub Message
-
-=head2 Message
-
- 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'} );
-}
-
-# }}}
-
-# {{{ sub Content
-
-=head2 Content PARAMHASH
-
-If this transaction has attached mime objects, returns the first text/plain 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.
-
-
-=cut
-
-sub Content {
- my $self = shift;
- my %args = (
- Quote => 0,
- Wrap => 70,
- @_
- );
-
- my $content;
- my $content_obj = $self->ContentObj;
- if ($content_obj) {
- $content = $content_obj->Content;
- }
-
- # If all else fails, return a message that we couldn't find any content
- else {
- $content = $self->loc('This transaction appears to have no content');
- }
-
- if ( $args{'Quote'} ) {
-
- # Remove quoted signature.
- $content =~ s/\n-- \n(.*)$//s;
-
- # What's the longest line like?
- my $max = 0;
- 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 = '['
- . $self->CreatorObj->Name() . ' - '
- . $self->CreatedAsString() . "]:\n\n" . $content . "\n\n";
- $content =~ s/^/> /gm;
-
- }
-
- return ($content);
-}
-
-# }}}
-
-# {{{ ContentObj
-
-=head2 ContentObj
-
-Returns the RT::Attachment object which contains the content for this Transaction
-
-=cut
-
-
-
-sub ContentObj {
-
- my $self = shift;
-
- # If we don\'t have any content, return undef now.
- unless ( $self->Attachments->First ) {
- return (undef);
- }
-
- # Get the set of toplevel attachments to this transaction.
- my $Attachment = $self->Attachments->First();
-
- # If it's a message or a plain part, just return the
- # body.
- if ( $Attachment->ContentType() =~ '^(text/plain$|message/)' ) {
- return ($Attachment);
- }
-
- # If it's a multipart object, first try returning the first
- # text/plain part.
-
- elsif ( $Attachment->ContentType() =~ '^multipart/' ) {
- my $plain_parts = $Attachment->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 '' ) {
- return ( $plain_parts->First );
- }
-
- # If that fails, return the first text/plain or message/ part
- # which has some content.
-
- else {
- my $all_parts = $Attachment->Children();
- while ( my $part = $all_parts->Next ) {
- if (( $part->ContentType() =~ '^(text/plain$|message/)' ) && $part->Content() ) {
- return ($part);
- }
- }
- }
-
- }
-
- # We found no content. suck
- return (undef);
-}
-
-# }}}
-
-# {{{ sub Subject
-
-=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->Attachments->First ) {
- return ( $self->Attachments->First->Subject );
- }
- else {
- return (undef);
- }
-}
-
-# }}}
-
-# {{{ sub Attachments
-
-=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.
-
-=cut
-
-sub Attachments {
- my $self = shift;
-
- unless ( $self->{'attachments'} ) {
- $self->{'attachments'} = RT::Attachments->new( $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 ( $self->{'attachments'} );
- }
- }
-
- #if they ain't got rights to see, return an empty object
- else {
- unless ( $self->CurrentUserHasRight('ShowTicket') ) {
- return ( $self->{'attachments'} );
- }
- }
-
- $self->{'attachments'}->Limit( FIELD => 'TransactionId',
- VALUE => $self->Id );
-
- # Get the self->{'attachments'} in the order they're put into
- # the database. Arguably, we should be returning a tree
- # of self->{'attachments'}, not a set...but no current app seems to need
- # it.
-
- $self->{'attachments'}->OrderBy( ALIAS => 'main',
- FIELD => 'id',
- ORDER => 'asc' );
-
- }
- return ( $self->{'attachments'} );
-
-}
-
-# }}}
-
-# {{{ sub _Attach
-
-=head2 _Attach
-
-A private method used to attach a mime object to this transaction.
-
-=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->loc("[_1]: no attachment specified", $self) );
- }
-
- my $Attachment = new RT::Attachment( $self->CurrentUser );
- $Attachment->Create(
- TransactionId => $self->Id,
- Attachment => $MIMEObject
- );
- return ( $Attachment, $self->loc("Attachment created") );
-
-}
-
-# }}}
-
-# }}}
-
-# {{{ Routines dealing with Transaction Attributes
-
-# {{{ sub Description
-
-=head2 Description
-
-Returns a text string which describes this transaction
-
-=cut
-
-sub Description {
- my $self = shift;
-
- #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 ( $self->loc("Permission Denied") );
- }
- }
-
- #if they ain't got rights to see, don't let em
- else {
- unless ( $self->CurrentUserHasRight('ShowTicket') ) {
- return ($self->loc("Permission Denied") );
- }
- }
-
- if ( !defined( $self->Type ) ) {
- return ( $self->loc("No transaction type specified"));
- }
-
- return ( $self->loc("[_1] by [_2]",$self->BriefDescription , $self->CreatorObj->Name ));
-}
-
-# }}}
-
-# {{{ sub BriefDescription
-
-=head2 BriefDescription
-
-Returns a text string which briefly describes this transaction
-
-=cut
-
-sub BriefDescription {
- my $self = shift;
-
-
- #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 ( $self->loc("Permission Denied") );
- }
- }
-
- #if they ain't got rights to see, don't let em
- else {
- unless ( $self->CurrentUserHasRight('ShowTicket') ) {
- return ( $self->loc("Permission Denied") );
- }
- }
-
- my $type = $self->Type; #cache this, rather than calling it 30 times
-
- if ( !defined( $type ) ) {
- return $self->loc("No transaction type specified");
- }
-
- if ( $type eq 'Create' ) {
- return ($self->loc("Ticket created"));
- }
- elsif ( $type =~ /Status/ ) {
- if ( $self->Field eq 'Status' ) {
- if ( $self->NewValue eq 'deleted' ) {
- return ($self->loc("Ticket deleted"));
- }
- else {
- return ( $self->loc("Status changed from [_1] to [_2]", $self->loc($self->OldValue), $self->loc($self->NewValue) ));
-
- }
- }
-
- # Generic:
- my $no_value = $self->loc("(no value)");
- return ( $self->loc( "[_1] changed from [_2] to [_3]", $self->Field , ( $self->OldValue || $no_value ) , $self->NewValue ));
- }
-
- if (my $code = $_BriefDescriptions{$type}) {
- return $code->($self);
- }
-
- return $self->loc( "Default: [_1]/[_2] changed from [_3] to [_4]", $type, $self->Field, $self->OldValue, $self->NewValue );
-}
-
-%_BriefDescriptions = (
- Correspond => sub {
- my $self = shift;
- return $self->loc("Correspondence added");
- },
- Comment => sub {
- my $self = shift;
- return $self->loc("Comments added");
- },
- CustomField => sub {
- my $self = shift;
- my $field = $self->loc('CustomField');
-
- if ( $self->Field ) {
- my $cf = RT::CustomField->new( $self->CurrentUser );
- $cf->Load( $self->Field );
- $field = $cf->Name();
- }
-
- if ( $self->OldValue eq '' ) {
- return ( $self->loc("[_1] [_2] added", $field, $self->NewValue) );
- }
- elsif ( $self->NewValue eq '' ) {
- return ( $self->loc("[_1] [_2] deleted", $field, $self->OldValue) );
-
- }
- else {
- return $self->loc("[_1] [_2] changed to [_3]", $field, $self->OldValue, $self->NewValue );
- }
- },
- Untake => sub {
- my $self = shift;
- return $self->loc("Untaken");
- },
- Take => sub {
- my $self = shift;
- return $self->loc("Taken");
- },
- Force => sub {
- my $self = shift;
- my $Old = RT::User->new( $self->CurrentUser );
- $Old->Load( $self->OldValue );
- my $New = RT::User->new( $self->CurrentUser );
- $New->Load( $self->NewValue );
-
- return $self->loc("Owner forcibly changed from [_1] to [_2]" , $Old->Name , $New->Name);
- },
- Steal => sub {
- my $self = shift;
- my $Old = RT::User->new( $self->CurrentUser );
- $Old->Load( $self->OldValue );
- return $self->loc("Stolen from [_1] ", $Old->Name);
- },
- Give => sub {
- my $self = shift;
- my $New = RT::User->new( $self->CurrentUser );
- $New->Load( $self->NewValue );
- return $self->loc( "Given to [_1]", $New->Name );
- },
- AddWatcher => sub {
- my $self = shift;
- my $principal = RT::Principal->new($self->CurrentUser);
- $principal->Load($self->NewValue);
- return $self->loc( "[_1] [_2] added", $self->Field, $principal->Object->Name);
- },
- DelWatcher => sub {
- my $self = shift;
- my $principal = RT::Principal->new($self->CurrentUser);
- $principal->Load($self->OldValue);
- return $self->loc( "[_1] [_2] deleted", $self->Field, $principal->Object->Name);
- },
- Subject => sub {
- my $self = shift;
- return $self->loc( "Subject changed to [_1]", $self->Data );
- },
- AddLink => sub {
- my $self = shift;
- my $value;
- if ( $self->NewValue ) {
- my $URI = RT::URI->new( $self->CurrentUser );
- $URI->FromURI( $self->NewValue );
- if ( $URI->Resolver ) {
- $value = $URI->Resolver->AsString;
- }
- else {
- $value = $self->NewValue;
- }
- if ( $self->Field eq 'DependsOn' ) {
- return $self->loc( "Dependency on [_1] added", $value );
- }
- elsif ( $self->Field eq 'DependedOnBy' ) {
- return $self->loc( "Dependency by [_1] added", $value );
-
- }
- elsif ( $self->Field eq 'RefersTo' ) {
- return $self->loc( "Reference to [_1] added", $value );
- }
- elsif ( $self->Field eq 'ReferredToBy' ) {
- return $self->loc( "Reference by [_1] added", $value );
- }
- elsif ( $self->Field eq 'MemberOf' ) {
- return $self->loc( "Membership in [_1] added", $value );
- }
- elsif ( $self->Field eq 'HasMember' ) {
- return $self->loc( "Member [_1] added", $value );
- }
- }
- else {
- return ( $self->Data );
- }
- },
- DeleteLink => sub {
- my $self = shift;
- my $value;
- if ( $self->OldValue ) {
- my $URI = RT::URI->new( $self->CurrentUser );
- $URI->FromURI( $self->OldValue );
- if ( $URI->Resolver ) {
- $value = $URI->Resolver->AsString;
- }
- else {
- $value = $self->OldValue;
- }
-
- if ( $self->Field eq 'DependsOn' ) {
- return $self->loc( "Dependency on [_1] deleted", $value );
- }
- elsif ( $self->Field eq 'DependedOnBy' ) {
- return $self->loc( "Dependency by [_1] deleted", $value );
-
- }
- elsif ( $self->Field eq 'RefersTo' ) {
- return $self->loc( "Reference to [_1] deleted", $value );
- }
- elsif ( $self->Field eq 'ReferredToBy' ) {
- return $self->loc( "Reference by [_1] deleted", $value );
- }
- elsif ( $self->Field eq 'MemberOf' ) {
- return $self->loc( "Membership in [_1] deleted", $value );
- }
- elsif ( $self->Field eq 'HasMember' ) {
- return $self->loc( "Member [_1] deleted", $value );
- }
- }
- else {
- return ( $self->Data );
- }
- },
- Set => sub {
- my $self = shift;
- 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->loc("[_1] changed from [_2] to [_3]", $self->Field , $q1->Name , $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->loc( "[_1] changed from [_2] to [_3]", $self->Field, $t2->AsString, $t1->AsString );
- }
- else {
- return $self->loc( "[_1] changed from [_2] to [_3]", $self->Field, $self->OldValue, $self->NewValue );
- }
- },
- PurgeTransaction => sub {
- my $self = shift;
- return $self->loc("Transaction [_1] purged", $self->Data);
- },
-);
-
-# }}}
-
-# {{{ Utility methods
-
-# {{{ sub IsInbound
-
-=head2 IsInbound
-
-Returns true if the creator of the transaction is a requestor of the ticket.
-Returns false otherwise
-
-=cut
-
-sub IsInbound {
- my $self = shift;
- return ( $self->TicketObj->IsRequestor( $self->CreatorObj->PrincipalId ) );
-}
-
-# }}}
-
-# }}}
-
-sub _ClassAccessible {
- {
-
- id => { read => 1, type => 'int(11)', default => '' },
- EffectiveTicket =>
- { read => 1, write => 1, type => 'int(11)', default => '' },
- Ticket =>
- { read => 1, public => 1, type => 'int(11)', default => '' },
- TimeTaken => { read => 1, type => 'int(11)', default => '' },
- Type => { read => 1, type => 'varchar(20)', default => '' },
- Field => { read => 1, type => 'varchar(40)', default => '' },
- OldValue => { read => 1, type => 'varchar(255)', default => '' },
- NewValue => { read => 1, type => 'varchar(255)', default => '' },
- Data => { read => 1, type => 'varchar(100)', default => '' },
- Creator => { read => 1, auto => 1, type => 'int(11)', default => '' },
- Created =>
- { read => 1, auto => 1, type => 'datetime', default => '' },
-
- }
-};
-
-# }}}
-
-# }}}
-
-# {{{ sub _Set
-
-sub _Set {
- my $self = shift;
- return ( 0, $self->loc('Transactions are immutable') );
-}
-
-# }}}
-
-# {{{ sub _Value
-
-=head2 _Value
-
-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 CurrentUserHasRight
-
-=head2 CurrentUserHasRight RIGHT
-
-Calls $self->CurrentUser->HasQueueRight for the right passed in here.
-passed in here.
-
-=cut
-
-sub CurrentUserHasRight {
- my $self = shift;
- my $right = shift;
- return (
- $self->CurrentUser->HasRight(
- Right => "$right",
- Object => $self->TicketObj
- )
- );
-}
-
-# }}}
-
-# Transactions don't change. by adding this cache congif directiove, we don't lose pathalogically on long tickets.
-sub _CacheConfig {
- {
- 'cache_p' => 1,
- 'fast_update_p' => 1,
- 'cache_for_sec' => 180,
- }
-}
-1;