expand M/V/C to Model/View/Controller for sub-container resolution
[catagits/Catalyst-Runtime.git] / lib / Catalyst.pm
index 35c6ca9..7c03083 100644 (file)
@@ -67,7 +67,7 @@ our $GO        = Catalyst::Exception::Go->new;
 #I imagine that very few of these really need to be class variables. if any.
 #maybe we should just make them attributes with a default?
 __PACKAGE__->mk_classdata($_)
-  for qw/components arguments dispatcher engine log dispatcher_class
+  for qw/container components arguments dispatcher engine log dispatcher_class
   engine_class context_class request_class response_class stats_class
   setup_finished/;
 
@@ -79,7 +79,7 @@ __PACKAGE__->stats_class('Catalyst::Stats');
 
 # Remember to update this in Catalyst::Runtime as well!
 
-our $VERSION = '5.80029';
+our $VERSION = '5.80032';
 
 sub import {
     my ( $class, @arguments ) = @_;
@@ -1109,6 +1109,7 @@ sub setup {
         }
     }
 
+    $class->setup_config();
     $class->setup_home( delete $flags->{home} );
 
     $class->setup_log( delete $flags->{log} );
@@ -1241,7 +1242,7 @@ EOF
 A hook to attach modifiers to. This method does not do anything except set the
 C<setup_finished> accessor.
 
-Applying method modifiers to the C<setup> method doesn't work, because of quirky thingsdone for plugin setup.
+Applying method modifiers to the C<setup> method doesn't work, because of quirky things done for plugin setup.
 
 Example:
 
@@ -1660,7 +1661,9 @@ sub execute {
     push( @{ $c->stack }, $code );
 
     no warnings 'recursion';
-    eval { $c->state( $code->execute( $class, $c, @{ $c->req->args } ) || 0 ) };
+    # N.B. This used to be combined, but I have seen $c get clobbered if so, and
+    #      I have no idea how, ergo $ret (which appears to fix the issue)
+    eval { my $ret = $code->execute( $class, $c, @{ $c->req->args } ) || 0; $c->state( $ret ) };
 
     $c->_stats_finish_execute( $stats_info ) if $c->use_stats and $stats_info;
 
@@ -1682,8 +1685,8 @@ sub execute {
                 $error = qq/Caught exception in $class->$name "$error"/;
             }
             $c->error($error);
-            $c->state(0);
         }
+        $c->state(0);
     }
     return $c->state;
 }
@@ -1857,7 +1860,7 @@ sub finalize_headers {
     }
 
     # Content-Length
-    if ( $response->body && !$response->content_length ) {
+    if ( defined $response->body && length $response->body && !$response->content_length ) {
 
         # get the length from a filehandle
         if ( blessed( $response->body ) && $response->body->can('read') || ref( $response->body ) eq 'GLOB' )
@@ -2362,11 +2365,11 @@ sub prepare_write { my $c = shift; $c->engine->prepare_write( $c, @_ ) }
 
 =head2 $c->request_class
 
-Returns or sets the request class.
+Returns or sets the request class. Defaults to L<Catalyst::Request>.
 
 =head2 $c->response_class
 
-Returns or sets the response class.
+Returns or sets the response class. Defaults to L<Catalyst::Response>.
 
 =head2 $c->read( [$maxlength] )
 
@@ -2409,6 +2412,35 @@ Sets up actions for a component.
 
 sub setup_actions { my $c = shift; $c->dispatcher->setup_actions( $c, @_ ) }
 
+=head2 $c->setup_config
+
+=cut
+
+sub setup_config {
+    my $class = shift;
+
+    my %args = %{$class->config || {} };
+    my @container_classes = qw/MyApp::Container Catalyst::Container/;
+    unshift @container_classes, delete $args{container_class} if exists $args{container_class};
+
+    my $container_class = Class::MOP::load_first_existing_class(@container_classes);
+
+    my $container = $container_class->new( %args, name => "$class" );
+
+    $container->add_sub_container(Bread::Board::Container->new( name => $_ )) for qw(model controller view);
+    $class->container($container);
+
+    my $config = $container->fetch('config')->get;
+    $class->config($config);
+    $class->finalize_config; # back-compat
+}
+
+=head $c->finalize_config
+
+=cut
+
+sub finalize_config { }
+
 =head2 $c->setup_components
 
 This method is called internally to set up the application's components.
@@ -2446,8 +2478,18 @@ sub setup_components {
         Catalyst::Utils::ensure_class_loaded( $component, { ignore_loaded => 1 } );
     }
 
+    my $containers;
+    $containers->{$_} = $class->container->get_sub_container($_) for qw(model view controller);
+
     for my $component (@comps) {
         my $instance = $class->components->{ $component } = $class->setup_component($component);
+        my $type = lc((split /::/, $component)[1]);
+        if ($deprecatedcatalyst_component_names) {
+            $type = 'controller' if $type eq 'c';
+            $type = 'model' if $type eq 'm';
+            $type = 'view' if $type eq 'v';
+        }
+        $containers->{$type}->add_service(Bread::Board::BlockInjection->new( name => $component, block => sub { return $instance } ));
         my @expanded_components = $instance->can('expand_modules')
             ? $instance->expand_modules( $component, $config )
             : $class->expand_component_module( $component, $config );
@@ -3224,6 +3266,12 @@ Yuval Kogman, C<nothingmuch@woobling.org>
 
 rainboxx: Matthias Dietrich, C<perl@rainboxx.de>
 
+dd070: Dhaval Dhanani <dhaval070@gmail.com>
+
+=head1 COPYRIGHT
+
+Copyright (c) 2005, the above named PROJECT FOUNDER and CONTRIBUTORS.
+
 =head1 LICENSE
 
 This library is free software. You can redistribute it and/or modify it under