aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgroditi <groditi@03d0b0b2-0e1a-0410-a411-fdb2f4bd65d7>2008-11-11 21:08:20 +0000
committergroditi <groditi@03d0b0b2-0e1a-0410-a411-fdb2f4bd65d7>2008-11-11 21:08:20 +0000
commit747a1feb2d49d2dba85f997fa2f4542a17800331 (patch)
treebd1d5330d907dff7befe227f1bcdd20b7ef911ed
parent7ea45b2aff36dd61953b1517a1cfb079dcea230c (diff)
downloadreaction-747a1feb2d49d2dba85f997fa2f4542a17800331.tar.gz
reaction-747a1feb2d49d2dba85f997fa2f4542a17800331.zip
fix leaks via make_context_closure
-rw-r--r--lib/Reaction/UI/Controller.pm8
-rw-r--r--lib/Reaction/UI/Controller/Collection/CRUD.pm30
2 files changed, 24 insertions, 14 deletions
diff --git a/lib/Reaction/UI/Controller.pm b/lib/Reaction/UI/Controller.pm
index 76b562e..fc2f597 100644
--- a/lib/Reaction/UI/Controller.pm
+++ b/lib/Reaction/UI/Controller.pm
@@ -7,6 +7,7 @@ use base qw(
);
use Reaction::Class;
+use Scalar::Util 'weaken';
sub push_viewport {
my $self = shift;
@@ -73,6 +74,13 @@ sub redirect_to {
$c->res->redirect($uri);
}
+sub make_context_closure {
+ my($self, $closure) = @_;
+ my $ctx = $self->context;
+ weaken $ctx;
+ return sub { $closure->($ctx, @_) };
+}
+
1;
__END__;
diff --git a/lib/Reaction/UI/Controller/Collection/CRUD.pm b/lib/Reaction/UI/Controller/Collection/CRUD.pm
index 1d8e4cc..352b142 100644
--- a/lib/Reaction/UI/Controller/Collection/CRUD.pm
+++ b/lib/Reaction/UI/Controller/Collection/CRUD.pm
@@ -34,61 +34,63 @@ sub get_model_action {
my ($self, $c, $name, $target) = @_;
return $target->action_for($name, ctx => $c);
}
-
sub create :Chained('base') :PathPart('create') :Args(0) {
my ($self, $c) = @_;
+ my $apply = sub { $self->after_create_callback( @_) };
+ my $close = sub { $self->on_create_close_callback( @_) };
my $vp_args = {
- on_apply_callback => sub { $self->after_create_callback( @_); },
- on_close_callback => sub { $self->on_create_close_callback( @_) }
+ on_apply_callback => $self->make_context_closure($apply),
+ on_close_callback => $self->make_context_closure($close),
};
$self->basic_model_action( $c, $vp_args);
}
sub delete_all :Chained('base') :PathPart('delete_all') :Args(0) {
my ($self, $c) = @_;
+ my $close = sub { $self->on_delete_all_close_callback( @_) };
$self->basic_model_action( $c, {
- on_close_callback => sub { $self->on_delete_all_close_callback( @_) }
+ on_close_callback => $self->make_context_closure($close),
});
}
sub on_delete_all_close_callback {
- my($self) = @_;
- $self->redirect_to($self->context, 'list');
+ my($self, $c) = @_;
+ $self->redirect_to($c, 'list');
}
sub after_create_callback {
- my ($self, $vp, $result) = @_;
- my $c = $self->context;
+ my ($self, $c, $vp, $result) = @_;
return $self->redirect_to
( $c, 'update', [ @{$c->req->captures}, $result->id ] );
}
sub on_create_close_callback {
my($self, $c, $vp) = @_;
- $self->redirect_to( $self->context, 'list' );
+ $self->redirect_to( $c, 'list' );
}
sub update :Chained('object') :Args(0) {
my ($self, $c) = @_;
+ my $close = sub { $self->on_update_close_callback( @_) };
my $vp_args = {
- on_close_callback => sub { $self->on_update_close_callback( @_ ) }
+ on_close_callback => $self->make_context_closure($close),
};
$self->basic_model_action( $c, $vp_args);
}
sub on_update_close_callback {
- my($self) = @_;
+ my($self, $c) = @_;
#this needs a better solution. currently thinking about it
- my $c = $self->context;
- my @cap = @{ $c->req->captures };
+ my @cap = @{$c->req->captures};
pop(@cap); # object id
$self->redirect_to($c, 'list', \@cap);
}
sub delete :Chained('object') :Args(0) {
my ($self, $c) = @_;
+ my $close = sub { $self->on_update_close_callback( @_) };
my $vp_args = {
- on_close_callback => sub { $self->on_update_close_callback( @_) }
+ on_close_callback => $self->make_context_closure($close),
};
$self->basic_model_action( $c, $vp_args);
}