X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Runtime.git;a=blobdiff_plain;f=lib%2FCatalyst%2FDispatchType%2FChained.pm;h=f5ae7ad26054a5382cd9e96c792256ac0abbe55d;hp=c22604bfbf35e56f27caccb3a6d120785f33bf4e;hb=6b49572336514157cdddf44ca9b9c80886c842f6;hpb=8b13f357b71297872a61f142ae62c2e60fda304d diff --git a/lib/Catalyst/DispatchType/Chained.pm b/lib/Catalyst/DispatchType/Chained.pm index c22604b..f5ae7ad 100644 --- a/lib/Catalyst/DispatchType/Chained.pm +++ b/lib/Catalyst/DispatchType/Chained.pm @@ -85,7 +85,7 @@ sub list { $paths->row(@$_) for @rows; } - $c->log->debug( "Loaded Path Part actions:\n" . $paths->draw ); + $c->log->debug( "Loaded Chained actions:\n" . $paths->draw . "\n" ); } =head2 $self->match( $c, $path ) @@ -101,7 +101,8 @@ sub match { my @parts = split('/', $path); - my ($chain, $captures) = $self->recurse_match($c, '/', \@parts); + my ($chain, $captures, $parts) = $self->recurse_match($c, '/', \@parts); + push @{$c->req->args}, @$parts if $parts && @$parts; return 0 unless $chain; @@ -126,6 +127,7 @@ sub recurse_match { my ( $self, $c, $parent, $path_parts ) = @_; my $children = $self->{children_of}{$parent}; return () unless $children; + my $best_action; my @captures; TRY: foreach my $try_part (sort { length($b) <=> length($a) } keys %$children) { @@ -141,6 +143,10 @@ sub recurse_match { my @try_actions = @{$children->{$try_part}}; TRY_ACTION: foreach my $action (@try_actions) { if (my $capture_attr = $action->attributes->{CaptureArgs}) { + + # Short-circuit if not enough remaining parts + next TRY_ACTION unless @parts >= $capture_attr->[0]; + my @captures; my @parts = @parts; # localise @@ -148,22 +154,33 @@ sub recurse_match { push(@captures, splice(@parts, 0, $capture_attr->[0])); # try the remaining parts against children of this action - my ($actions, $captures) = $self->recurse_match( + my ($actions, $captures, $action_parts) = $self->recurse_match( $c, '/'.$action->reverse, \@parts ); - if ($actions) { - return [ $action, @$actions ], [ @captures, @$captures ]; + if ($actions && (!$best_action || $#$action_parts < $#{$best_action->{parts}})){ + $best_action = { + actions => [ $action, @$actions ], + captures=> [ @captures, @$captures ], + parts => $action_parts + }; } - } else { + } + else { { local $c->req->{arguments} = [ @{$c->req->args}, @parts ]; next TRY_ACTION unless $action->match($c); } - push(@{$c->req->args}, @parts); - return [ $action ], [ ]; + if (!$best_action || $#parts < $#{$best_action->{parts}}){ + $best_action = { + actions => [ $action ], + captures=> [], + parts => \@parts + } + } } } } + return @$best_action{qw/actions captures parts /} if $best_action; return (); } @@ -192,7 +209,11 @@ sub register { if ($parent eq '.') { $parent = '/'.$action->namespace; } elsif ($parent !~ m/^\//) { - $parent = '/'.join('/', $action->namespace, $parent); + if ($action->namespace) { + $parent = '/'.join('/', $action->namespace, $parent); + } else { + $parent = '/'.$parent; # special case namespace '' (root) + } } } else { $parent = '/' @@ -453,7 +474,7 @@ effect as using C<:PathPart>, it would default to the action name. Has to be specified for every child in the chain. Possible values are absolute and relative private action paths, with the relatives pointing to the current controller, or a single slash C to tell Catalyst that -this is the root of a chain. The attribute C<:Chained> without aguments +this is the root of a chain. The attribute C<:Chained> without arguments also defaults to the C behavior. Because you can specify an absolute path to the parent action, it