1 package Catalyst::ActionChain;
4 extends qw(Catalyst::Action);
6 has chain => (is => 'rw');
11 Catalyst::ActionChain - Chain of Catalyst Actions
15 See L<Catalyst::Manual::Intro> for more info about Chained actions.
19 This class represents a chain of Catalyst Actions. It behaves exactly like
20 the action at the *end* of the chain except on dispatch it will execute all
21 the actions in the chain in order.
26 my ( $self, $c ) = @_;
27 my @captures = @{$c->req->captures||[]};
28 my @chain = @{ $self->chain };
29 my $last = pop(@chain);
30 foreach my $action ( @chain ) {
32 if (my $cap = $action->number_of_captures) {
33 @args = splice(@captures, 0, $cap);
35 local $c->request->{arguments} = \@args;
36 $action->dispatch( $c );
38 # break the chain if exception occurs in the middle of chain. We
39 # check the global config flag 'abort_chain_on_error_fix', but this
40 # is now considered true by default, so unless someone explicitly sets
41 # it to false we default it to true (if its not defined).
42 my $abort = defined($c->config->{abort_chain_on_error_fix}) ?
43 $c->config->{abort_chain_on_error_fix} : 1;
44 return if ($c->has_errors && $abort);
46 $last->dispatch( $c );
50 my ( $self, $actions ) = @_;
51 my $final = $actions->[-1];
52 return $self->new({ %$final, chain => $actions });
55 sub number_of_captures {
57 my $chain = $self->chain;
60 $captures += $_->number_of_captures for @$chain;
65 my ($self, $c, $captures) = @_;
66 my @captures = @{$captures||[]};
68 foreach my $link(@{$self->chain}) {
69 my @local_captures = splice @captures,0,$link->number_of_captures;
70 return unless $link->match_captures($c, \@local_captures);
74 sub match_captures_constraints {
75 my ($self, $c, $captures) = @_;
76 my @captures = @{$captures||[]};
78 foreach my $link(@{$self->chain}) {
79 my @local_captures = splice @captures,0,$link->number_of_captures;
80 next unless $link->has_captures_constraints;
81 return unless $link->match_captures_constraints($c, \@local_captures);
86 # the scheme defined at the end of the chain is the one we use
87 # but warn if too many.
91 my @chain = @{ $self->chain };
92 my ($scheme, @more) = map {
93 exists $_->attributes->{Scheme} ? $_->attributes->{Scheme}[0] : ();
96 warn "$self is a chain with two many Scheme attributes (only one is allowed)"
102 __PACKAGE__->meta->make_immutable;
111 Accessor for the action chain; will be an arrayref of the Catalyst::Action
112 objects encapsulated by this chain.
114 =head2 dispatch( $c )
116 Dispatch this action chain against a context; will dispatch the encapsulated
119 =head2 from_chain( \@actions )
121 Takes a list of Catalyst::Action objects and constructs and returns a
122 Catalyst::ActionChain object representing a chain of these actions
124 =head2 number_of_captures
126 Returns the total number of captures for the entire chain of actions.
128 =head2 match_captures
130 Match all the captures that this chain encloses, if any.
134 Any defined scheme for the actionchain
142 Catalyst Contributors, see Catalyst.pm
146 This library is free software. You can redistribute it and/or modify it under
147 the same terms as Perl itself.