Path done
[catagits/Catalyst-Runtime.git] / lib / Catalyst / DispatchType / Chained.pm
index bee76f1..0dc4c25 100644 (file)
@@ -1,7 +1,10 @@
 package Catalyst::DispatchType::Chained;
 
-use strict;
-use base qw/Catalyst::DispatchType/;
+use Moose;
+extends 'Catalyst::DispatchType';
+
+#use strict;
+#use base qw/Catalyst::DispatchType/;
 use Text::SimpleTable;
 use Catalyst::ActionChain;
 use URI;
@@ -102,7 +105,7 @@ sub match {
     my @parts = split('/', $path);
 
     my ($chain, $captures, $parts) = $self->recurse_match($c, '/', \@parts);
-       push @{$c->req->args}, @$parts;
+    push @{$c->req->args}, @$parts if $parts && @$parts;
 
     return 0 unless $chain;
 
@@ -127,7 +130,7 @@ sub recurse_match {
     my ( $self, $c, $parent, $path_parts ) = @_;
     my $children = $self->{children_of}{$parent};
     return () unless $children;
-       my $best_action;
+    my $best_action;
     my @captures;
     TRY: foreach my $try_part (sort { length($b) <=> length($a) }
                                    keys %$children) {
@@ -157,30 +160,41 @@ sub recurse_match {
                 my ($actions, $captures, $action_parts) = $self->recurse_match(
                                              $c, '/'.$action->reverse, \@parts
                                            );
-                               if ($actions && (!$best_action || $#$action_parts < $#{$best_action->{parts}})){
-                                       $best_action = {
-                                               actions => [ $action, @$actions ],
-                                               captures=> [ @captures, @$captures ],
-                                               parts   => $action_parts
-                                               };
-                               }
-               }
-                       else {
+                if ($actions && (!$best_action || $#$action_parts < $#{$best_action->{parts}})){
+                    $best_action = {
+                        actions => [ $action, @$actions ],
+                        captures=> [ @captures, @$captures ],
+                        parts   => $action_parts
+                        };
+                }
+            }
+            else {
                 {
                     local $c->req->{arguments} = [ @{$c->req->args}, @parts ];
                     next TRY_ACTION unless $action->match($c);
                 }
-                               if (!$best_action || $#parts < $#{$best_action->{parts}}){
-                       $best_action = {
-                                               actions => [ $action ],
-                                               captures=> [],
-                                               parts   => \@parts
-                                               }
-                                       }
+                my $args_attr = $action->attributes->{Args}->[0];
+
+                #    No best action currently
+                # OR This one matches with fewer parts left than the current best action,
+                #    And therefore is a better match
+                # OR No parts and this expects 0
+                #    The current best action might also be Args(0),
+                #    but we couldn't chose between then anyway so we'll take the last seen
+
+                if (!$best_action                       ||
+                    @parts < @{$best_action->{parts}}   ||
+                    (!@parts && $args_attr eq 0)){
+                    $best_action = {
+                        actions => [ $action ],
+                        captures=> [],
+                        parts   => \@parts
+                    }
+                }
             }
         }
     }
-       return @$best_action{qw/actions captures parts /} if $best_action;
+    return @$best_action{qw/actions captures parts/} if $best_action;
     return ();
 }
 
@@ -291,7 +305,7 @@ sub uri_for_action {
     return undef if @captures; # fail for too many captures
 
     return join('/', '', @parts);
-   
+
 }
 
 =head1 USAGE
@@ -452,7 +466,7 @@ this debugging output:
   '-----------------------+------------------------------'
   ...
 
-Here's a more detailed specification of the attributes belonging to 
+Here's a more detailed specification of the attributes belonging to
 C<:Chained>:
 
 =head2 Attributes