use Devel::InnerPackage ();
use File::stat;
use Module::Pluggable::Object ();
-use NEXT;
use Text::SimpleTable ();
use Path::Class::Dir ();
use Path::Class::File ();
BEGIN { require 5.008001; }
-__PACKAGE__->mk_accessors(
- qw/counter request response state action stack namespace stats stash/
-);
+has stack => (is => 'rw');
+has stash => (is => 'rw');
+has state => (is => 'rw');
+has stats => (is => 'rw');
+has action => (is => 'rw');
+has counter => (is => 'rw');
+has request => (is => 'rw');
+has response => (is => 'rw');
+has namespace => (is => 'rw');
+
attributes->import( __PACKAGE__, \&namespace, 'lvalue' );
our $RECURSION = 1000;
our $DETACH = "catalyst_detach\n";
+#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
engine_class context_class request_class response_class stats_class
my $caller = caller(0);
+ #why does called have to ISA Catalyst and ISA Controller ?
+ #Convert test suite to not use the behavior where Myapp ISA Controller
+ # after that is done we can eliminate that little mess.
unless ( $caller->isa('Catalyst') ) {
no strict 'refs';
- push @{"$caller\::ISA"}, $class, 'Catalyst::Controller';
+ if( $caller->can('meta') ){
+ my @superclasses = ($caller->meta->superclasses, $class, 'Catalyst::Controller');
+ #my @superclasses = ($caller->meta->superclasses, $class);
+ $caller->meta->superclasses(@superclasses);
+ } else {
+ push @{"$caller\::ISA"}, $class, 'Catalyst::Controller';
+ #push @{"$caller\::ISA"}, $class;
+ }
}
$caller->arguments( [@arguments] );
=cut
-sub config {
+around config => sub {
+ my $orig = shift;
my $c = shift;
$c->log->warn("Setting config after setup has been run is not a good idea.")
if ( @_ and $c->setup_finished );
- $c->NEXT::config(@_);
-}
+ $c->$orig(@_);
+};
=head2 $c->log
=cut
+#Why does this exist? This is no longer safe and WILL NOT WORK.
+# it doesnt seem to be used anywhere. can we remove it?
sub _localize_fields {
my ( $c, $localized, $code ) = ( @_ );
}
# Allow engine to handle finalize flow (for POE)
- if ( $c->engine->can('finalize') ) {
- $c->engine->finalize($c);
+ my $engine = $c->engine;
+ if ( my $code = $engine->can('finalize') ) {
+ $engine->$code($c);
}
else {
sub finalize_headers {
my $c = shift;
+ my $response = $c->response; #accessor calls can add up?
+
+ # Moose TODO: Maybe this should be an attribute too?
# Check if we already finalized headers
- return if $c->response->{_finalized_headers};
+ return if $response->{_finalized_headers};
# Handle redirects
- if ( my $location = $c->response->redirect ) {
+ if ( my $location = $response->redirect ) {
$c->log->debug(qq/Redirecting to "$location"/) if $c->debug;
- $c->response->header( Location => $location );
+ $response->header( Location => $location );
- if ( !$c->response->body ) {
+ #Moose TODO: we should probably be using a predicate method here ?
+ if ( !$response->body ) {
# Add a default body if none is already present
- $c->response->body(
+ $response->body(
qq{<html><body><p>This item has moved <a href="$location">here</a>.</p></body></html>}
);
}
}
# Content-Length
- if ( $c->response->body && !$c->response->content_length ) {
+ if ( $response->body && !$response->content_length ) {
# get the length from a filehandle
- if ( blessed( $c->response->body ) && $c->response->body->can('read') )
+ if ( blessed( $response->body ) && $response->body->can('read') )
{
- my $stat = stat $c->response->body;
+ my $stat = stat $response->body;
if ( $stat && $stat->size > 0 ) {
- $c->response->content_length( $stat->size );
+ $response->content_length( $stat->size );
}
else {
$c->log->warn('Serving filehandle without a content-length');
}
else {
# everything should be bytes at this point, but just in case
- $c->response->content_length( bytes::length( $c->response->body ) );
+ $response->content_length( bytes::length( $response->body ) );
}
}
# Errors
- if ( $c->response->status =~ /^(1\d\d|[23]04)$/ ) {
- $c->response->headers->remove_header("Content-Length");
- $c->response->body('');
+ if ( $response->status =~ /^(1\d\d|[23]04)$/ ) {
+ $response->headers->remove_header("Content-Length");
+ $response->body('');
}
$c->finalize_cookies;
$c->engine->finalize_headers( $c, @_ );
# Done
- $c->response->{_finalized_headers} = 1;
+ $response->{_finalized_headers} = 1;
}
=head2 $c->finalize_output
}
$COUNT++;
+ #todo: reuse coderef from can
$class->log->_flush() if $class->log->can('_flush');
return $status;
}
sub prepare {
my ( $class, @arguments ) = @_;
+ #moose todo: context_class as attr with default
$class->context_class( ref $class || $class ) unless $class->context_class;
+ #Moose TODO: if we make empty containers the defaults then that can be
+ #handled by the context class itself instead of having this here
my $c = $class->context_class->new(
{
counter => {},
}
);
+ #surely this is not the most efficient way to do things...
$c->stats($class->stats_class->new)->enable($c->use_stats);
if ( $c->debug ) {
$c->res->headers->header( 'X-Catalyst' => $Catalyst::VERSION );
$c->request->_context($c);
$c->response->_context($c);
+ #XXX reuse coderef from can
# Allow engine to direct the prepare flow (for POE)
if ( $c->engine->can('prepare') ) {
$c->engine->prepare( $c, @arguments );
sub prepare_body {
my $c = shift;
+ #Moose TODO: what is _body ??
# Do we run for the first time?
return if defined $c->request->{_body};
# we know M::P::O found a file on disk so this is safe
Catalyst::Utils::ensure_class_loaded( $component, { ignore_loaded => 1 } );
+ #Class::MOP::load_class($component);
my $module = $class->setup_component( $component );
my %modules = (
$dispatcher = $class->dispatcher_class;
}
- unless (Class::Inspector->loaded($dispatcher)) {
- require Class::Inspector->filename($dispatcher);
- }
+ Class::MOP::load_class($dispatcher);
# dispatcher instance
$class->dispatcher( $dispatcher->new );
$engine = $class->engine_class;
}
- unless (Class::Inspector->loaded($engine)) {
- require Class::Inspector->filename($engine);
- }
+ Class::MOP::load_class($engine);
+ #unless (Class::Inspector->loaded($engine)) {
+ # require Class::Inspector->filename($engine);
+ #}
# check for old engines that are no longer compatible
my $old_engine;
$home = $env;
}
- unless ($home) {
- $home = Catalyst::Utils::home($class);
- }
+ $home ||= Catalyst::Utils::home($class);
if ($home) {
+ #I remember recently being scolded for assigning config values like this
$class->config->{home} ||= $home;
$class->config->{root} ||= Path::Class::Dir->new($home)->subdir('root');
}
my $env_debug = Catalyst::Utils::env_value( $class, 'DEBUG' );
if ( defined($env_debug) ? $env_debug : $debug ) {
no strict 'refs';
+ #Moose todo: dying to be made a bool attribute
*{"$class\::debug"} = sub { 1 };
$class->log->debug('Debug messages enabled');
}
my $env = Catalyst::Utils::env_value( $class, 'STATS' );
if ( defined($env) ? $env : ($stats || $class->debug ) ) {
no strict 'refs';
+ #Moose todo: dying to be made a bool attribute
*{"$class\::use_stats"} = sub { 1 };
$class->log->debug('Statistics enabled');
}
# no ignore_loaded here, the plugin may already have been
# defined in memory and we don't want to error on "no file" if so
- Catalyst::Utils::ensure_class_loaded( $plugin );
+ Class::MOP::load_class( $plugin );
$proto->_plugins->{$plugin} = 1;
unless ($instant) {
no strict 'refs';
- unshift @{"$class\::ISA"}, $plugin;
+ if( $class->can('meta') ){
+ my @superclasses = ($plugin, $class->meta->superclasses );
+ $class->meta->superclasses(@superclasses);
+ } else {
+ unshift @{"$class\::ISA"}, $plugin;
+ }
}
return $class;
}