#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
=head2 Web based interface (WebUI)
Shredder's WebUI integrates into RT's WebUI. You can find it in the
-Configuration->Tools->Shredder tab. The interface is similar to the
+Admin->Tools->Shredder tab. The interface is similar to the
CLI and gives you the same functionality. You can find 'Shredder' link
at the bottom of tickets search results, so you could wipeout tickets
in the way similar to the bulk update.
=cut
-our $VERSION = '0.04';
use File::Spec ();
### after: push @INC, qw(@RT_LIB_PATH@);
use RT::Shredder::Constants;
use RT::Shredder::Exceptions;
-
- require RT;
-
- require RT::Shredder::Record;
-
- require RT::Shredder::ACE;
- require RT::Shredder::Attachment;
- require RT::Shredder::CachedGroupMember;
- require RT::Shredder::CustomField;
- require RT::Shredder::CustomFieldValue;
- require RT::Shredder::GroupMember;
- require RT::Shredder::Group;
- require RT::Shredder::Link;
- require RT::Shredder::Principal;
- require RT::Shredder::Queue;
- require RT::Shredder::Scrip;
- require RT::Shredder::ScripAction;
- require RT::Shredder::ScripCondition;
- require RT::Shredder::Template;
- require RT::Shredder::ObjectCustomFieldValue;
- require RT::Shredder::Ticket;
- require RT::Shredder::Transaction;
- require RT::Shredder::User;
}
our @SUPPORTED_OBJECTS = qw(
%opt = @_;
RT::LoadConfig();
RT::Init();
+ return;
}
=head4 new
{
my $proto = shift;
my $self = bless( {}, ref $proto || $proto );
- $self->_Init( @_ );
- return $self;
+ return $self->_Init( @_ );
}
sub _Init
$self->{'cache'} = {};
$self->{'resolver'} = {};
$self->{'dump_plugins'} = [];
+ return $self;
}
=head4 CastObjectsToRecords( Objects => undef )
}
} elsif ( UNIVERSAL::isa( $targets, 'SCALAR' ) || !ref $targets ) {
$targets = $$targets if ref $targets;
- my ($class, $id) = split /-/, $targets;
+ my ($class, $org, $id);
+ if ($targets =~ /-.*-/) {
+ ($class, $org, $id) = split /-/, $targets;
+ RT::Shredder::Exception->throw( "Can't wipeout remote object $targets" )
+ unless $org eq RT->Config->Get('Organization');
+ } else {
+ ($class, $id) = split /-/, $targets;
+ }
RT::Shredder::Exception->throw( "Unsupported class $class" )
unless $class =~ /^\w+(::\w+)*$/;
$class = 'RT::'. $class unless $class =~ /^RTx?::/i;
- eval "require $class";
- die "Couldn't load '$class' module" if $@;
+ $class->require or die "Failed to load $class: $@";
my $obj = $class->new( RT->SystemUser );
die "Couldn't construct new '$class' object" unless $obj;
$obj->Load( $id );
RT::Shredder::Exception->throw( "Unsupported type '". (ref $obj || $obj || '(undef)')."'" );
}
- my $str = $obj->_AsString;
- return ($self->{'cache'}->{ $str } ||= { State => ON_STACK, Object => $obj } );
+ my $str = $obj->UID;
+ return ($self->{'cache'}->{ $str } ||= {
+ State => RT::Shredder::Constants::ON_STACK,
+ Object => $obj
+ } );
}
=head4 GetObject, GetState, GetRecord( String => ''| Object => '' )
Carp::croak( "both String and Object args passed" );
}
return $args{'String'} if $args{'String'};
- return $args{'Object'}->_AsString if UNIVERSAL::can($args{'Object'}, '_AsString' );
+ return $args{'Object'}->UID if UNIVERSAL::can($args{'Object'}, 'UID' );
return '';
}
my $self = $_[0];
foreach my $cache_val ( values %{ $self->{'cache'} } ) {
- next if $cache_val->{'State'} & (WIPED | IN_WIPING);
+ next if $cache_val->{'State'} & (RT::Shredder::Constants::WIPED | RT::Shredder::Constants::IN_WIPING);
$self->Wipeout( Object => $cache_val->{'Object'} );
}
+ return;
}
sub Wipeout
die $error if RT::Shredder::Exception::Info->caught;
die "Couldn't wipeout object: $error";
}
+ return;
}
sub _Wipeout
my $record = $args{'CacheRecord'};
$record = $self->PutObject( Object => $args{'Object'} ) unless $record;
- return if $record->{'State'} & (WIPED | IN_WIPING);
+ return if $record->{'State'} & (RT::Shredder::Constants::WIPED | RT::Shredder::Constants::IN_WIPING);
- $record->{'State'} |= IN_WIPING;
+ $record->{'State'} |= RT::Shredder::Constants::IN_WIPING;
my $object = $record->{'Object'};
$self->DumpObject( Object => $object, State => 'before any action' );
my $deps = $object->Dependencies( Shredder => $self );
$deps->List(
- WithFlags => DEPENDS_ON | VARIABLE,
+ WithFlags => RT::Shredder::Constants::DEPENDS_ON | RT::Shredder::Constants::VARIABLE,
Callback => sub { $self->ApplyResolvers( Dependency => $_[0] ) },
);
$self->DumpObject( Object => $object, State => 'after resolvers' );
$deps->List(
- WithFlags => DEPENDS_ON,
- WithoutFlags => WIPE_AFTER | VARIABLE,
+ WithFlags => RT::Shredder::Constants::DEPENDS_ON,
+ WithoutFlags => RT::Shredder::Constants::WIPE_AFTER | RT::Shredder::Constants::VARIABLE,
Callback => sub { $self->_Wipeout( Object => $_[0]->TargetObject ) },
);
$self->DumpObject( Object => $object, State => 'after wiping dependencies' );
$object->__Wipeout;
- $record->{'State'} |= WIPED; delete $record->{'Object'};
+ $record->{'State'} |= RT::Shredder::Constants::WIPED; delete $record->{'Object'};
$self->DumpObject( Object => $object, State => 'after wipeout' );
$deps->List(
- WithFlags => DEPENDS_ON | WIPE_AFTER,
- WithoutFlags => VARIABLE,
+ WithFlags => RT::Shredder::Constants::DEPENDS_ON | RT::Shredder::Constants::WIPE_AFTER,
+ WithoutFlags => RT::Shredder::Constants::VARIABLE,
Callback => sub { $self->_Wipeout( Object => $_[0]->TargetObject ) },
);
$self->DumpObject( Object => $object, State => 'after late dependencies' );
return;
}
-sub ValidateRelations
-{
- my $self = shift;
- my %args = ( @_ );
-
- foreach my $record( values %{ $self->{'cache'} } ) {
- next if( $record->{'State'} & VALID );
- $record->{'Object'}->ValidateRelations( Shredder => $self );
- }
-}
-
=head3 Data storage and backups
=head4 GetFileName( FileName => '<ISO DATETIME>-XXXX.sql', FromStorage => 1 )
my ($state, $msg) = $_->Run( %args );
die "Couldn't run plugin: $msg" unless $state;
}
+ return;
}
{ my $mark = 1; # XXX: integer overflows?
sub PopDumpMark {
my $self = shift;
foreach (@{ $self->{'dump_plugins'} }) {
- my ($state, $msg) = $_->PushMark( @_ );
+ my ($state, $msg) = $_->PopMark( @_ );
die "Couldn't pop mark: $msg" unless $state;
}
+ return;
}
sub RollbackDumpTo {
my $self = shift;
my ($state, $msg) = $_->RollbackTo( @_ );
die "Couldn't rollback to mark: $msg" unless $state;
}
+ return;
}
}