improved forward()
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Engine.pm
index 3b4b758..98766fb 100644 (file)
@@ -286,6 +286,7 @@ If you define a class without method it will default to process().
 sub forward {
     my $c       = shift;
     my $command = shift;
+    $c->state(0);
     unless ($command) {
         $c->log->debug('Nothing to forward to') if $c->debug;
         return 0;
@@ -301,22 +302,13 @@ sub forward {
     }
     my $results = $c->get_action( $command, $namespace );
     if ( @{$results} ) {
-        if ( $command =~ /^\!/ ) {
-            for my $result ( @{$results} ) {
-                my ( $class, $code ) = @{ $result->[0] };
-                $c->state( $c->process( $class, $code ) );
-            }
-        }
-        else {
-            return 0 unless my $result = $results->[0];
-            if ( $result->[2] ) {
+        unless ( $command =~ /^\!/ ) {
+            $results = [ pop @{$results} ];
+            if ( $results->[0]->[2] ) {
                 $c->log->debug(qq/Couldn't forward "$command" to regex action/)
                   if $c->debug;
                 return 0;
             }
-            my ( $class, $code ) = @{ $result->[0] };
-            $class = $c->components->{$class} || $class;
-            $c->state( $c->process( $class, $code ) );
         }
     }
     else {
@@ -328,8 +320,7 @@ sub forward {
         my $method = shift || 'process';
         if ( my $code = $class->can($method) ) {
             $c->actions->{reverse}->{"$code"} = "$class->$method";
-            $class = $c->comp($class) || $class;
-            $c->state( $c->process( $class, $code ) );
+            $results = [ [ [ $class, $code ] ] ];
         }
         else {
             $c->log->debug(qq/Couldn't forward to "$class->$method"/)
@@ -337,6 +328,11 @@ sub forward {
             return 0;
         }
     }
+    for my $result ( @{$results} ) {
+        my ( $class, $code ) = @{ $result->[0] };
+        $class = $c->comp->{$class} || $class;
+        $c->state( $c->process( $class, $code ) );
+    }
     return $c->state;
 }
 
@@ -356,15 +352,20 @@ sub get_action {
         my $result = $c->actions->{private}->{ $parent->getUID }->{$action};
         push @results, [$result] if $result;
         my $visitor = Tree::Simple::Visitor::FindByPath->new;
+        my $local;
         for my $part ( split '/', $namespace ) {
+            $local = undef;
             $visitor->setSearchPath($part);
             $parent->accept($visitor);
             my $child = $visitor->getResult;
             my $uid   = $child->getUID if $child;
             my $match = $c->actions->{private}->{$uid}->{$action} if $uid;
+            return [ [$match] ] if ( $match && $match =~ /^?.*/ );
+            $local = $c->actions->{private}->{$uid}->{"?$action"} if $uid;
             push @results, [$match] if $match;
             $parent = $child if $child;
         }
+        return [ [$local] ] if $local;
         return \@results;
     }
     elsif ( my $p = $c->actions->{plain}->{$action} ) { return [ [$p] ] }
@@ -482,8 +483,8 @@ sub prepare {
     }
     $c->prepare_request($r);
     $c->prepare_path;
-    $c->prepare_headers;
     $c->prepare_cookies;
+    $c->prepare_headers;
     $c->prepare_connection;
     my $method   = $c->req->method   || '';
     my $path     = $c->req->path     || '';
@@ -670,7 +671,6 @@ Set an action in a given namespace.
 
 sub set_action {
     my ( $c, $action, $code, $namespace ) = @_;
-
     my $prefix = '';
     if ( $action =~ /^\?(.*)$/ ) {
         my $prefix = $1 || '';
@@ -678,7 +678,7 @@ sub set_action {
         $action = $prefix . _prefix( $namespace, $action );
         $c->actions->{plain}->{$action} = [ $namespace, $code ];
     }
-    if ( $action =~ /^\/(.*)\/$/ ) {
+    elsif ( $action =~ /^\/(.*)\/$/ ) {
         my $regex = $1;
         $c->actions->{compiled}->{qr#$regex#} = $action;
         $c->actions->{regex}->{$action} = [ $namespace, $code ];
@@ -704,15 +704,10 @@ sub set_action {
         $c->actions->{private}->{$uid}->{$action} = [ $namespace, $code ];
         $action = "!$action";
     }
-    else {
-        $c->actions->{plain}->{$action} = [ $namespace, $code ];
-    }
-
+    else { $c->actions->{plain}->{$action} = [ $namespace, $code ] }
     my $reverse = $prefix ? "$action ($prefix)" : $action;
     $c->actions->{reverse}->{"$code"} = $reverse;
-
-    $c->log->debug(qq/"$namespace" defined "$action" as "$code"/)
-      if $c->debug;
+    $c->log->debug(qq/"$namespace" defined "$action" as "$code"/) if $c->debug;
 }
 
 =item $class->setup
@@ -791,6 +786,7 @@ sub stash {
 sub _prefix {
     my ( $class, $name ) = @_;
     my $prefix = _class2prefix($class);
+    warn "$class - $name - $prefix";
     $name = "$prefix/$name" if $prefix;
     return $name;
 }