controller method on application, this one is identical to that one in Context -...
[catagits/Catalyst-Runtime.git] / lib / Catalyst.pm
1 package Catalyst;
2
3 use Moose;
4 use Moose::Meta::Class ();
5 extends 'Catalyst::Component';
6 use Moose::Util qw/find_meta/;
7 use B::Hooks::EndOfScope ();
8 use Catalyst::Exception;
9 use Catalyst::Log;
10 use Catalyst::Utils;
11 use Catalyst::Controller;
12 use Catalyst::Context;
13 use Devel::InnerPackage ();
14 use Module::Pluggable::Object ();
15 use Text::SimpleTable ();
16 use Path::Class::Dir ();
17 use Path::Class::File ();
18 use Tree::Simple::Visitor::FindByUID;
19 use Class::C3::Adopt::NEXT;
20 use attributes;
21 use utf8;
22 use Carp qw/croak carp shortmess/;
23
24 BEGIN { require 5.008004; }
25
26 sub comp { shift->component(@_) }
27
28 #I imagine that very few of these really need to be class variables. if any.
29 #maybe we should just make them attributes with a default?
30 __PACKAGE__->mk_classdata($_)
31   for qw/components arguments dispatcher engine log dispatcher_class
32   engine_class context_class request_class response_class stats_class
33   setup_finished/;
34
35 __PACKAGE__->context_class('Catalyst::Context');
36 __PACKAGE__->dispatcher_class('Catalyst::Dispatcher');
37 __PACKAGE__->engine_class('Catalyst::Engine::CGI');
38 __PACKAGE__->request_class('Catalyst::Request');
39 __PACKAGE__->response_class('Catalyst::Response');
40 __PACKAGE__->stats_class('Catalyst::Stats');
41
42 # Remember to update this in Catalyst::Runtime as well!
43
44 our $VERSION = '5.80013';
45
46 {
47     my $dev_version = $VERSION =~ /_\d{2}$/;
48     *_IS_DEVELOPMENT_VERSION = sub () { $dev_version };
49 }
50
51 $VERSION = eval $VERSION;
52
53 our $COUNT     = 1;
54 our $START     = time;
55 our $DETACH    = Catalyst::Exception::Detach->new;
56 our $GO        = Catalyst::Exception::Go->new;
57
58 sub import {
59     my ( $class, @arguments ) = @_;
60
61     # We have to limit $class to Catalyst to avoid pushing Catalyst upon every
62     # callers @ISA.
63     return unless $class eq 'Catalyst';
64
65     my $caller = caller();
66     return if $caller eq 'main';
67
68     # Kill Adopt::NEXT warnings if we're a non-RC version
69     unless (_IS_DEVELOPMENT_VERSION()) {
70         Class::C3::Adopt::NEXT->unimport(qr/^Catalyst::/);
71     }
72
73     my $meta = Moose::Meta::Class->initialize($caller);
74     unless ( $caller->isa('Catalyst') ) {
75         my @superclasses = ($meta->superclasses, $class, 'Catalyst::Controller');
76         $meta->superclasses(@superclasses);
77     }
78     # Avoid possible C3 issues if 'Moose::Object' is already on RHS of MyApp
79     $meta->superclasses(grep { $_ ne 'Moose::Object' } $meta->superclasses);
80
81     unless( $meta->has_method('meta') ){
82         $meta->add_method(meta => sub { Moose::Meta::Class->initialize("${caller}") } );
83     }
84
85     $caller->arguments( [@arguments] );
86     $caller->setup_home;
87 }
88
89 sub _application { $_[0] }
90
91 =head1 NAME
92
93 Catalyst - The Elegant MVC Web Application Framework
94
95 =head1 SYNOPSIS
96
97 See the L<Catalyst::Manual> distribution for comprehensive
98 documentation and tutorials.
99
100     # Install Catalyst::Devel for helpers and other development tools
101     # use the helper to create a new application
102     catalyst.pl MyApp
103
104     # add models, views, controllers
105     script/myapp_create.pl model MyDatabase DBIC::Schema create=static dbi:SQLite:/path/to/db
106     script/myapp_create.pl view MyTemplate TT
107     script/myapp_create.pl controller Search
108
109     # built in testserver -- use -r to restart automatically on changes
110     # --help to see all available options
111     script/myapp_server.pl
112
113     # command line testing interface
114     script/myapp_test.pl /yada
115
116     ### in lib/MyApp.pm
117     use Catalyst qw/-Debug/; # include plugins here as well
118
119     ### In lib/MyApp/Controller/Root.pm (autocreated)
120     sub foo : Global { # called for /foo, /foo/1, /foo/1/2, etc.
121         my ( $self, $c, @args ) = @_; # args are qw/1 2/ for /foo/1/2
122         $c->stash->{template} = 'foo.tt'; # set the template
123         # lookup something from db -- stash vars are passed to TT
124         $c->stash->{data} =
125           $c->model('Database::Foo')->search( { country => $args[0] } );
126         if ( $c->req->params->{bar} ) { # access GET or POST parameters
127             $c->forward( 'bar' ); # process another action
128             # do something else after forward returns
129         }
130     }
131
132     # The foo.tt TT template can use the stash data from the database
133     [% WHILE (item = data.next) %]
134         [% item.foo %]
135     [% END %]
136
137     # called for /bar/of/soap, /bar/of/soap/10, etc.
138     sub bar : Path('/bar/of/soap') { ... }
139
140     # called for all actions, from the top-most controller downwards
141     sub auto : Private {
142         my ( $self, $c ) = @_;
143         if ( !$c->user_exists ) { # Catalyst::Plugin::Authentication
144             $c->res->redirect( '/login' ); # require login
145             return 0; # abort request and go immediately to end()
146         }
147         return 1; # success; carry on to next action
148     }
149
150     # called after all actions are finished
151     sub end : Private {
152         my ( $self, $c ) = @_;
153         if ( scalar @{ $c->error } ) { ... } # handle errors
154         return if $c->res->body; # already have a response
155         $c->forward( 'MyApp::View::TT' ); # render template
156     }
157
158     ### in MyApp/Controller/Foo.pm
159     # called for /foo/bar
160     sub bar : Local { ... }
161
162     # called for /blargle
163     sub blargle : Global { ... }
164
165     # an index action matches /foo, but not /foo/1, etc.
166     sub index : Private { ... }
167
168     ### in MyApp/Controller/Foo/Bar.pm
169     # called for /foo/bar/baz
170     sub baz : Local { ... }
171
172     # first Root auto is called, then Foo auto, then this
173     sub auto : Private { ... }
174
175     # powerful regular expression paths are also possible
176     sub details : Regex('^product/(\w+)/details$') {
177         my ( $self, $c ) = @_;
178         # extract the (\w+) from the URI
179         my $product = $c->req->captures->[0];
180     }
181
182 See L<Catalyst::Manual::Intro> for additional information.
183
184 =head1 DESCRIPTION
185
186 Catalyst is a modern framework for making web applications without the
187 pain usually associated with this process. This document is a reference
188 to the main Catalyst application. If you are a new user, we suggest you
189 start with L<Catalyst::Manual::Tutorial> or L<Catalyst::Manual::Intro>.
190
191 See L<Catalyst::Manual> for more documentation.
192
193 Catalyst plugins can be loaded by naming them as arguments to the "use
194 Catalyst" statement. Omit the C<Catalyst::Plugin::> prefix from the
195 plugin name, i.e., C<Catalyst::Plugin::My::Module> becomes
196 C<My::Module>.
197
198     use Catalyst qw/My::Module/;
199
200 If your plugin starts with a name other than C<Catalyst::Plugin::>, you can
201 fully qualify the name by using a unary plus:
202
203     use Catalyst qw/
204         My::Module
205         +Fully::Qualified::Plugin::Name
206     /;
207
208 Special flags like C<-Debug> and C<-Engine> can also be specified as
209 arguments when Catalyst is loaded:
210
211     use Catalyst qw/-Debug My::Module/;
212
213 The position of plugins and flags in the chain is important, because
214 they are loaded in the order in which they appear.
215
216 The following flags are supported:
217
218 =head2 -Debug
219
220 Enables debug output. You can also force this setting from the system
221 environment with CATALYST_DEBUG or <MYAPP>_DEBUG. The environment
222 settings override the application, with <MYAPP>_DEBUG having the highest
223 priority.
224
225 =head2 -Engine
226
227 Forces Catalyst to use a specific engine. Omit the
228 C<Catalyst::Engine::> prefix of the engine name, i.e.:
229
230     use Catalyst qw/-Engine=CGI/;
231
232 =head2 -Home
233
234 Forces Catalyst to use a specific home directory, e.g.:
235
236     use Catalyst qw[-Home=/usr/mst];
237
238 This can also be done in the shell environment by setting either the
239 C<CATALYST_HOME> environment variable or C<MYAPP_HOME>; where C<MYAPP>
240 is replaced with the uppercased name of your application, any "::" in
241 the name will be replaced with underscores, e.g. MyApp::Web should use
242 MYAPP_WEB_HOME. If both variables are set, the MYAPP_HOME one will be used.
243
244 =head2 -Log
245
246     use Catalyst '-Log=warn,fatal,error';
247
248 Specifies a comma-delimited list of log levels.
249
250 =head2 -Stats
251
252 Enables statistics collection and reporting. You can also force this setting
253 from the system environment with CATALYST_STATS or <MYAPP>_STATS. The
254 environment settings override the application, with <MYAPP>_STATS having the
255 highest priority.
256
257 e.g.
258
259    use Catalyst qw/-Stats=1/
260
261 =head1 METHODS
262
263 =cut
264
265 =head2 $c->controller($name)
266
267 Gets a L<Catalyst::Controller> instance by name.
268
269     $c->controller('Foo')->do_stuff;
270
271 If the name is omitted, will return the controller for the dispatched
272 action.
273
274 If you want to search for controllers, pass in a regexp as the argument.
275
276     # find all controllers that start with Foo
277     my @foo_controllers = $c->controller(qr{^Foo});
278
279
280 =cut
281
282 sub controller {
283     my ( $c, $name, @args ) = @_;
284
285     if( $name ) {
286         my @result = $c->_comp_search_prefixes( $name, qw/Controller C/ );
287         return map { $c->_filter_component( $_, @args ) } @result if ref $name;
288         return $c->_filter_component( $result[ 0 ], @args );
289     }
290
291     return $c->component( $c->action->class );
292 }
293
294 sub _comp_search_prefixes {
295     my $c = shift;
296     return map $c->components->{ $_ }, $c->_comp_names_search_prefixes(@_);
297 }
298
299 # search components given a name and some prefixes
300 sub _comp_names_search_prefixes {
301     my ( $c, $name, @prefixes ) = @_;
302     my $appclass = ref $c || $c;
303     my $filter   = "^${appclass}::(" . join( '|', @prefixes ) . ')::';
304     $filter = qr/$filter/; # Compile regex now rather than once per loop
305
306     # map the original component name to the sub part that we will search against
307     my %eligible = map { my $n = $_; $n =~ s{^$appclass\::[^:]+::}{}; $_ => $n; }
308         grep { /$filter/ } keys %{ $c->components };
309
310     # undef for a name will return all
311     return keys %eligible if !defined $name;
312
313     my $query  = ref $name ? $name : qr/^$name$/i;
314     my @result = grep { $eligible{$_} =~ m{$query} } keys %eligible;
315
316     return @result if @result;
317
318     # if we were given a regexp to search against, we're done.
319     return if ref $name;
320
321     # skip regexp fallback if configured
322     return
323         if $appclass->config->{disable_component_resolution_regex_fallback};
324
325     # regexp fallback
326     $query  = qr/$name/i;
327     @result = grep { $eligible{ $_ } =~ m{$query} } keys %eligible;
328
329     # no results? try against full names
330     if( !@result ) {
331         @result = grep { m{$query} } keys %eligible;
332     }
333
334     # don't warn if we didn't find any results, it just might not exist
335     if( @result ) {
336         # Disgusting hack to work out correct method name
337         my $warn_for = lc $prefixes[0];
338         my $msg = "Used regexp fallback for \$c->${warn_for}('${name}'), which found '" .
339            (join '", "', @result) . "'. Relying on regexp fallback behavior for " .
340            "component resolution is unreliable and unsafe.";
341         my $short = $result[0];
342         # remove the component namespace prefix
343         $short =~ s/.*?(Model|Controller|View):://;
344         my $shortmess = Carp::shortmess('');
345         if ($shortmess =~ m#Catalyst/Plugin#) {
346            $msg .= " You probably need to set '$short' instead of '${name}' in this " .
347               "plugin's config";
348         } elsif ($shortmess =~ m#Catalyst/lib/(View|Controller)#) {
349            $msg .= " You probably need to set '$short' instead of '${name}' in this " .
350               "component's config";
351         } else {
352            $msg .= " You probably meant \$c->${warn_for}('$short') instead of \$c->${warn_for}('${name}'), " .
353               "but if you really wanted to search, pass in a regexp as the argument " .
354               "like so: \$c->${warn_for}(qr/${name}/)";
355         }
356         $c->log->warn( "${msg}$shortmess" );
357     }
358
359     return @result;
360 }
361
362 # Find possible names for a prefix
363 sub _comp_names {
364     my ( $c, @prefixes ) = @_;
365     my $appclass = ref $c || $c;
366
367     my $filter = "^${appclass}::(" . join( '|', @prefixes ) . ')::';
368
369     my @names = map { s{$filter}{}; $_; }
370         $c->_comp_names_search_prefixes( undef, @prefixes );
371
372     return @names;
373 }
374
375 # Filter a component before returning by calling ACCEPT_CONTEXT if available
376 sub _filter_component {
377     my ( $c, $comp, @args ) = @_;
378
379     if ( eval { $comp->can('ACCEPT_CONTEXT'); } ) {
380         return $comp->ACCEPT_CONTEXT( $c, @args );
381     }
382
383     return $comp;
384 }
385
386 =head2 COMPONENT ACCESSORS
387
388 =head2 $c->controllers
389
390 Returns the available names which can be passed to $c->controller
391
392 =cut
393
394 sub controllers {
395     my ( $c ) = @_;
396     return $c->_comp_names(qw/Controller C/);
397 }
398
399 =head2 $c->models
400
401 Returns the available names which can be passed to $c->model
402
403 =cut
404
405 sub models {
406     my ( $c ) = @_;
407     return $c->_comp_names(qw/Model M/);
408 }
409
410
411 =head2 $c->views
412
413 Returns the available names which can be passed to $c->view
414
415 =cut
416
417 sub views {
418     my ( $c ) = @_;
419     return $c->_comp_names(qw/View V/);
420 }
421
422 =head2 $c->comp($name)
423
424 =head2 $c->component($name)
425
426 Gets a component object by name. This method is not recommended,
427 unless you want to get a specific component by full
428 class. C<< $c->controller >>, C<< $c->model >>, and C<< $c->view >>
429 should be used instead.
430
431 If C<$name> is a regexp, a list of components matched against the full
432 component name will be returned.
433
434 If Catalyst can't find a component by name, it will fallback to regex
435 matching by default. To disable this behaviour set
436 disable_component_resolution_regex_fallback to a true value.
437     
438     __PACKAGE__->config( disable_component_resolution_regex_fallback => 1 );
439
440 =cut
441
442 sub component {
443     my ( $c, $name, @args ) = @_;
444
445     if( $name ) {
446         my $comps = $c->components;
447
448         if( !ref $name ) {
449             # is it the exact name?
450             return $c->_filter_component( $comps->{ $name }, @args )
451                        if exists $comps->{ $name };
452
453             # perhaps we just omitted "MyApp"?
454             my $composed = ( ref $c || $c ) . "::${name}";
455             return $c->_filter_component( $comps->{ $composed }, @args )
456                        if exists $comps->{ $composed };
457
458             # search all of the models, views and controllers
459             my( $comp ) = $c->_comp_search_prefixes( $name, qw/Model M Controller C View V/ );
460             return $c->_filter_component( $comp, @args ) if $comp;
461         }
462
463         # This is here so $c->comp( '::M::' ) works
464         my $query = ref $name ? $name : qr{$name}i;
465
466         my @result = grep { m{$query} } keys %{ $c->components };
467         return map { $c->_filter_component( $_, @args ) } @result if ref $name;
468
469         if( $result[ 0 ] ) {
470             $c->log->warn( Carp::shortmess(qq(Found results for "${name}" using regexp fallback)) );
471             $c->log->warn( 'Relying on the regexp fallback behavior for component resolution' );
472             $c->log->warn( 'is unreliable and unsafe. You have been warned' );
473             return $c->_filter_component( $result[ 0 ], @args );
474         }
475
476         # I would expect to return an empty list here, but that breaks back-compat
477     }
478
479     # fallback
480     return sort keys %{ $c->components };
481 }
482
483 =head2 CLASS DATA AND HELPER CLASSES
484
485 =head2 $c->config
486
487 Returns or takes a hashref containing the application's configuration.
488
489     __PACKAGE__->config( { db => 'dsn:SQLite:foo.db' } );
490
491 You can also use a C<YAML>, C<XML> or L<Config::General> config file
492 like C<myapp.conf> in your applications home directory. See
493 L<Catalyst::Plugin::ConfigLoader>.
494
495 =head3 Cascading configuration
496
497 The config method is present on all Catalyst components, and configuration
498 will be merged when an application is started. Configuration loaded with
499 L<Catalyst::Plugin::ConfigLoader> takes precedence over other configuration,
500 followed by configuration in your top level C<MyApp> class. These two
501 configurations are merged, and then configuration data whose hash key matches a
502 component name is merged with configuration for that component.
503
504 The configuration for a component is then passed to the C<new> method when a
505 component is constructed.
506
507 For example:
508
509     MyApp->config({ 'Model::Foo' => { bar => 'baz', overrides => 'me' } });
510     MyApp::Model::Foo->config({ quux => 'frob', 'overrides => 'this' });
511
512 will mean that C<MyApp::Model::Foo> receives the following data when
513 constructed:
514
515     MyApp::Model::Foo->new({
516         bar => 'baz',
517         quux => 'frob',
518         overrides => 'me',
519     });
520
521 =cut
522
523 around config => sub {
524     my $orig = shift;
525     my $c = shift;
526
527     croak('Setting config after setup has been run is not allowed.')
528         if ( @_ and $c->setup_finished );
529
530     $c->$orig(@_);
531 };
532
533 =head2 $c->log
534
535 Returns the logging object instance. Unless it is already set, Catalyst
536 sets this up with a L<Catalyst::Log> object. To use your own log class,
537 set the logger with the C<< __PACKAGE__->log >> method prior to calling
538 C<< __PACKAGE__->setup >>.
539
540  __PACKAGE__->log( MyLogger->new );
541  __PACKAGE__->setup;
542
543 And later:
544
545     $c->log->info( 'Now logging with my own logger!' );
546
547 Your log class should implement the methods described in
548 L<Catalyst::Log>.
549
550
551 =head2 $c->debug
552
553 Returns 1 if debug mode is enabled, 0 otherwise.
554
555 You can enable debug mode in several ways:
556
557 =over
558
559 =item By calling myapp_server.pl with the -d flag
560
561 =item With the environment variables MYAPP_DEBUG, or CATALYST_DEBUG
562
563 =item The -Debug option in your MyApp.pm
564
565 =item By declaring C<sub debug { 1 }> in your MyApp.pm.
566
567 =back
568
569 Calling C<< $c->debug(1) >> has no effect.
570
571 =cut
572
573 sub debug { 0 }
574
575 =head2 $c->dispatcher
576
577 Returns the dispatcher instance. See L<Catalyst::Dispatcher>.
578
579 =head2 $c->engine
580
581 Returns the engine instance. See L<Catalyst::Engine>.
582
583
584 =head2 UTILITY METHODS
585
586 =head2 $c->path_to(@path)
587
588 Merges C<@path> with C<< $c->config->{home} >> and returns a
589 L<Path::Class::Dir> object. Note you can usually use this object as
590 a filename, but sometimes you will have to explicitly stringify it
591 yourself by calling the C<< ->stringify >> method.
592
593 For example:
594
595     $c->path_to( 'db', 'sqlite.db' );
596
597 =cut
598
599 sub path_to {
600     my ( $c, @path ) = @_;
601     my $path = Path::Class::Dir->new( $c->config->{home}, @path );
602     if ( -d $path ) { return $path }
603     else { return Path::Class::File->new( $c->config->{home}, @path ) }
604 }
605
606 =head2 $c->plugin( $name, $class, @args )
607
608 Helper method for plugins. It creates a class data accessor/mutator and
609 loads and instantiates the given class.
610
611     MyApp->plugin( 'prototype', 'HTML::Prototype' );
612
613     $c->prototype->define_javascript_functions;
614
615 B<Note:> This method of adding plugins is deprecated. The ability
616 to add plugins like this B<will be removed> in a Catalyst 5.81.
617 Please do not use this functionality in new code.
618
619 =cut
620
621 sub plugin {
622     my ( $class, $name, $plugin, @args ) = @_;
623
624     # See block comment in t/unit_core_plugin.t
625     $class->log->warn(qq/Adding plugin using the ->plugin method is deprecated, and will be removed in Catalyst 5.81/);
626
627     $class->_register_plugin( $plugin, 1 );
628
629     eval { $plugin->import };
630     $class->mk_classdata($name);
631     my $obj;
632     eval { $obj = $plugin->new(@args) };
633
634     if ($@) {
635         Catalyst::Exception->throw( message =>
636               qq/Couldn't instantiate instant plugin "$plugin", "$@"/ );
637     }
638
639     $class->$name($obj);
640     $class->log->debug(qq/Initialized instant plugin "$plugin" as "$name"/)
641       if $class->debug;
642 }
643
644 =head2 MyApp->setup
645
646 Initializes the dispatcher and engine, loads any plugins, and loads the
647 model, view, and controller components. You may also specify an array
648 of plugins to load here, if you choose to not load them in the C<use
649 Catalyst> line.
650
651     MyApp->setup;
652     MyApp->setup( qw/-Debug/ );
653
654 =cut
655
656 sub setup {
657     my ( $class, @arguments ) = @_;
658     croak('Running setup more than once')
659         if ( $class->setup_finished );
660
661     unless ( $class->isa('Catalyst') ) {
662
663         Catalyst::Exception->throw(
664             message => qq/'$class' does not inherit from Catalyst/ );
665     }
666
667     if ( $class->arguments ) {
668         @arguments = ( @arguments, @{ $class->arguments } );
669     }
670
671     # Process options
672     my $flags = {};
673
674     foreach (@arguments) {
675
676         if (/^-Debug$/) {
677             $flags->{log} =
678               ( $flags->{log} ) ? 'debug,' . $flags->{log} : 'debug';
679         }
680         elsif (/^-(\w+)=?(.*)$/) {
681             $flags->{ lc $1 } = $2;
682         }
683         else {
684             push @{ $flags->{plugins} }, $_;
685         }
686     }
687
688     $class->setup_home( delete $flags->{home} );
689
690     $class->setup_log( delete $flags->{log} );
691     $class->setup_plugins( delete $flags->{plugins} );
692     $class->setup_dispatcher( delete $flags->{dispatcher} );
693     $class->setup_engine( delete $flags->{engine} );
694     $class->setup_stats( delete $flags->{stats} );
695
696     for my $flag ( sort keys %{$flags} ) {
697
698         if ( my $code = $class->can( 'setup_' . $flag ) ) {
699             &$code( $class, delete $flags->{$flag} );
700         }
701         else {
702             $class->log->warn(qq/Unknown flag "$flag"/);
703         }
704     }
705
706     eval { require Catalyst::Devel; };
707     if( !$@ && $ENV{CATALYST_SCRIPT_GEN} && ( $ENV{CATALYST_SCRIPT_GEN} < $Catalyst::Devel::CATALYST_SCRIPT_GEN ) ) {
708         $class->log->warn(<<"EOF");
709 You are running an old script!
710
711   Please update by running (this will overwrite existing files):
712     catalyst.pl -force -scripts $class
713
714   or (this will not overwrite existing files):
715     catalyst.pl -scripts $class
716
717 EOF
718     }
719
720     if ( $class->debug ) {
721         my @plugins = map { "$_  " . ( $_->VERSION || '' ) } $class->registered_plugins;
722
723         if (@plugins) {
724             my $column_width = Catalyst::Utils::term_width() - 6;
725             my $t = Text::SimpleTable->new($column_width);
726             $t->row($_) for @plugins;
727             $class->log->debug( "Loaded plugins:\n" . $t->draw . "\n" );
728         }
729
730         my $dispatcher = $class->dispatcher;
731         my $engine     = $class->engine;
732         my $home       = $class->config->{home};
733
734         $class->log->debug(sprintf(q/Loaded dispatcher "%s"/, blessed($dispatcher)));
735         $class->log->debug(sprintf(q/Loaded engine "%s"/, blessed($engine)));
736
737         $home
738           ? ( -d $home )
739           ? $class->log->debug(qq/Found home "$home"/)
740           : $class->log->debug(qq/Home "$home" doesn't exist/)
741           : $class->log->debug(q/Couldn't find home/);
742     }
743
744     # Call plugins setup, this is stupid and evil.
745     # Also screws C3 badly on 5.10, hack to avoid.
746     {
747         no warnings qw/redefine/;
748         local *setup = sub { };
749         $class->setup unless $Catalyst::__AM_RESTARTING;
750     }
751
752     # Initialize our data structure
753     $class->components( {} );
754
755     $class->setup_components;
756
757     if ( $class->debug ) {
758         my $column_width = Catalyst::Utils::term_width() - 8 - 9;
759         my $t = Text::SimpleTable->new( [ $column_width, 'Class' ], [ 8, 'Type' ] );
760         for my $comp ( sort keys %{ $class->components } ) {
761             my $type = ref $class->components->{$comp} ? 'instance' : 'class';
762             $t->row( $comp, $type );
763         }
764         $class->log->debug( "Loaded components:\n" . $t->draw . "\n" )
765           if ( keys %{ $class->components } );
766     }
767
768     # Add our self to components, since we are also a component
769     if( $class->isa('Catalyst::Controller') ){
770       $class->components->{$class} = $class;
771     }
772
773     $class->setup_actions;
774
775     if ( $class->debug ) {
776         my $name = $class->config->{name} || 'Application';
777         $class->log->info("$name powered by Catalyst $Catalyst::VERSION");
778     }
779
780     # Make sure that the application class becomes immutable at this point,
781     B::Hooks::EndOfScope::on_scope_end {
782         return if $@;
783         my $meta = Class::MOP::get_metaclass_by_name($class);
784         if (
785             $meta->is_immutable
786             && ! { $meta->immutable_options }->{replace_constructor}
787             && (
788                    $class->isa('Class::Accessor::Fast')
789                 || $class->isa('Class::Accessor')
790             )
791         ) {
792             warn "You made your application class ($class) immutable, "
793                 . "but did not inline the\nconstructor. "
794                 . "This will break catalyst, as your app \@ISA "
795                 . "Class::Accessor(::Fast)?\nPlease pass "
796                 . "(replace_constructor => 1)\nwhen making your class immutable.\n";
797         }
798         $meta->make_immutable(
799             replace_constructor => 1,
800         ) unless $meta->is_immutable;
801     };
802
803     $class->setup_finalize;
804     # Should be the last thing we do so that user things hooking
805     # setup_finalize can log..
806     $class->log->_flush() if $class->log->can('_flush');
807     return 1; # Explicit return true as people have __PACKAGE__->setup as the last thing in their class. HATE.
808 }
809
810
811 =head2 $app->setup_finalize
812
813 A hook to attach modifiers to.
814 Using C<< after setup => sub{}; >> doesn't work, because of quirky things done for plugin setup.
815 Also better than C< setup_finished(); >, as that is a getter method.
816
817     sub setup_finalize {
818
819         my $app = shift;
820
821         ## do stuff, i.e., determine a primary key column for sessions stored in a DB
822
823         $app->next::method(@_);
824
825
826     }
827
828 =cut
829
830 sub setup_finalize {
831     my ($class) = @_;
832     $class->setup_finished(1);
833 }
834
835 =head2 $c->welcome_message
836
837 Returns the Catalyst welcome HTML page.
838
839 =cut
840
841 sub welcome_message {
842     my $c      = shift;
843     my $name   = $c->config->{name};
844     my $logo   = $c->uri_for('/static/images/catalyst_logo.png');
845     my $prefix = Catalyst::Utils::appprefix( ref $c );
846     $c->response->content_type('text/html; charset=utf-8');
847     return <<"EOF";
848 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
849     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
850 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
851     <head>
852     <meta http-equiv="Content-Language" content="en" />
853     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
854         <title>$name on Catalyst $VERSION</title>
855         <style type="text/css">
856             body {
857                 color: #000;
858                 background-color: #eee;
859             }
860             div#content {
861                 width: 640px;
862                 margin-left: auto;
863                 margin-right: auto;
864                 margin-top: 10px;
865                 margin-bottom: 10px;
866                 text-align: left;
867                 background-color: #ccc;
868                 border: 1px solid #aaa;
869             }
870             p, h1, h2 {
871                 margin-left: 20px;
872                 margin-right: 20px;
873                 font-family: verdana, tahoma, sans-serif;
874             }
875             a {
876                 font-family: verdana, tahoma, sans-serif;
877             }
878             :link, :visited {
879                     text-decoration: none;
880                     color: #b00;
881                     border-bottom: 1px dotted #bbb;
882             }
883             :link:hover, :visited:hover {
884                     color: #555;
885             }
886             div#topbar {
887                 margin: 0px;
888             }
889             pre {
890                 margin: 10px;
891                 padding: 8px;
892             }
893             div#answers {
894                 padding: 8px;
895                 margin: 10px;
896                 background-color: #fff;
897                 border: 1px solid #aaa;
898             }
899             h1 {
900                 font-size: 0.9em;
901                 font-weight: normal;
902                 text-align: center;
903             }
904             h2 {
905                 font-size: 1.0em;
906             }
907             p {
908                 font-size: 0.9em;
909             }
910             p img {
911                 float: right;
912                 margin-left: 10px;
913             }
914             span#appname {
915                 font-weight: bold;
916                 font-size: 1.6em;
917             }
918         </style>
919     </head>
920     <body>
921         <div id="content">
922             <div id="topbar">
923                 <h1><span id="appname">$name</span> on <a href="http://catalyst.perl.org">Catalyst</a>
924                     $VERSION</h1>
925              </div>
926              <div id="answers">
927                  <p>
928                  <img src="$logo" alt="Catalyst Logo" />
929                  </p>
930                  <p>Welcome to the  world of Catalyst.
931                     This <a href="http://en.wikipedia.org/wiki/MVC">MVC</a>
932                     framework will make web development something you had
933                     never expected it to be: Fun, rewarding, and quick.</p>
934                  <h2>What to do now?</h2>
935                  <p>That really depends  on what <b>you</b> want to do.
936                     We do, however, provide you with a few starting points.</p>
937                  <p>If you want to jump right into web development with Catalyst
938                     you might want to start with a tutorial.</p>
939 <pre>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Tutorial.pod">Catalyst::Manual::Tutorial</a></code>
940 </pre>
941 <p>Afterwards you can go on to check out a more complete look at our features.</p>
942 <pre>
943 <code>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Intro.pod">Catalyst::Manual::Intro</a>
944 <!-- Something else should go here, but the Catalyst::Manual link seems unhelpful -->
945 </code></pre>
946                  <h2>What to do next?</h2>
947                  <p>Next it's time to write an actual application. Use the
948                     helper scripts to generate <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AController%3A%3A&amp;mode=all">controllers</a>,
949                     <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AModel%3A%3A&amp;mode=all">models</a>, and
950                     <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AView%3A%3A&amp;mode=all">views</a>;
951                     they can save you a lot of work.</p>
952                     <pre><code>script/${prefix}_create.pl -help</code></pre>
953                     <p>Also, be sure to check out the vast and growing
954                     collection of <a href="http://search.cpan.org/search?query=Catalyst">plugins for Catalyst on CPAN</a>;
955                     you are likely to find what you need there.
956                     </p>
957
958                  <h2>Need help?</h2>
959                  <p>Catalyst has a very active community. Here are the main places to
960                     get in touch with us.</p>
961                  <ul>
962                      <li>
963                          <a href="http://dev.catalyst.perl.org">Wiki</a>
964                      </li>
965                      <li>
966                          <a href="http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst">Mailing-List</a>
967                      </li>
968                      <li>
969                          <a href="irc://irc.perl.org/catalyst">IRC channel #catalyst on irc.perl.org</a>
970                      </li>
971                  </ul>
972                  <h2>In conclusion</h2>
973                  <p>The Catalyst team hopes you will enjoy using Catalyst as much
974                     as we enjoyed making it. Please contact us if you have ideas
975                     for improvement or other feedback.</p>
976              </div>
977          </div>
978     </body>
979 </html>
980 EOF
981 }
982
983 =head1 INTERNAL METHODS
984
985 These methods are not meant to be used by end users.
986
987 =head2 $c->components
988
989 Returns a hash of components.
990
991 =head2 $c->context_class
992
993 Returns or sets the context class.
994
995 =head2 $c->dispatcher_class
996
997 Returns or sets the dispatcher class.
998
999 =head2 $c->engine_class
1000
1001 Returns or sets the engine class.
1002
1003 =head2 $c->handle_request( $class, @arguments )
1004
1005 Called to handle each HTTP request.
1006
1007 =cut
1008
1009 sub handle_request {
1010     my ( $class, @arguments ) = @_;
1011
1012     # Always expect worst case!
1013     my $status = -1;
1014     eval {
1015         if ($class->debug) {
1016             my $secs = time - $START || 1;
1017             my $av = sprintf '%.3f', $COUNT / $secs;
1018             my $time = localtime time;
1019             $class->log->info("*** Request $COUNT ($av/s) [$$] [$time] ***");
1020         }
1021
1022         my $c = $class->prepare(@arguments);
1023         $c->dispatch;
1024         $status = $c->finalize;
1025     };
1026
1027     if ( my $error = $@ ) {
1028         chomp $error;
1029         $class->log->error(qq/Caught exception in engine "$error"/);
1030     }
1031
1032     $COUNT++;
1033
1034     if(my $coderef = $class->log->can('_flush')){
1035         $class->log->$coderef();
1036     }
1037     return $status;
1038 }
1039
1040 =head2 $c->prepare( @arguments )
1041
1042 Creates a Catalyst context from an engine-specific request (Apache, CGI,
1043 etc.).
1044
1045 =cut
1046
1047 sub prepare {
1048     my ( $class, @arguments ) = @_;
1049
1050     # XXX
1051     # After the app/ctxt split, this should become an attribute based on something passed
1052     # into the application.
1053     $class->context_class( ref $class || $class ) unless $class->context_class;
1054
1055     my $app = $class->new({});
1056     my $c = $class->context_class->new( application => $app );
1057
1058     # For on-demand data
1059     $c->request->_context($c);
1060     $c->response->_context($c);
1061
1062     #surely this is not the most efficient way to do things...
1063     $c->stats($class->stats_class->new)->enable($c->use_stats);
1064     if ( $c->debug ) {
1065         $c->res->headers->header( 'X-Catalyst' => $Catalyst::VERSION );
1066     }
1067
1068     #XXX reuse coderef from can
1069     # Allow engine to direct the prepare flow (for POE)
1070     if ( $c->engine->can('prepare') ) {
1071         $c->engine->prepare( $c, @arguments );
1072     }
1073     else {
1074         $c->prepare_request(@arguments);
1075         $c->prepare_connection;
1076         $c->prepare_query_parameters;
1077         $c->prepare_headers;
1078         $c->prepare_cookies;
1079         $c->prepare_path;
1080
1081         # Prepare the body for reading, either by prepare_body
1082         # or the user, if they are using $c->read
1083         $c->prepare_read;
1084
1085         # Parse the body unless the user wants it on-demand
1086         unless ( $app->config->{parse_on_demand} ) {
1087             $c->prepare_body;
1088         }
1089     }
1090
1091     my $method  = $c->req->method  || '';
1092     my $path    = $c->req->path;
1093     $path       = '/' unless length $path;
1094     my $address = $c->req->address || '';
1095
1096     $c->log->debug(qq/"$method" request for "$path" from "$address"/)
1097       if $c->debug;
1098
1099     $c->prepare_action;
1100
1101     return $c;
1102 }
1103
1104 =head2 $c->request_class
1105
1106 Returns or sets the request class.
1107
1108 =head2 $c->response_class
1109
1110 Returns or sets the response class.
1111
1112 =head2 $c->run
1113
1114 Starts the engine.
1115
1116 =cut
1117
1118 sub run { my $c = shift; return $c->engine->run( $c, @_ ) }
1119
1120 =head2 $c->set_action( $action, $code, $namespace, $attrs )
1121
1122 Sets an action in a given namespace.
1123
1124 =cut
1125
1126 sub set_action { my $c = shift; $c->dispatcher->set_action( $c, @_ ) }
1127
1128 =head2 $c->setup_actions($component)
1129
1130 Sets up actions for a component.
1131
1132 =cut
1133
1134 sub setup_actions { my $c = shift; $c->dispatcher->setup_actions( $c, @_ ) }
1135
1136 =head2 $c->setup_components
1137
1138 This method is called internally to set up the application's components.
1139
1140 It finds modules by calling the L<locate_components> method, expands them to
1141 package names with the L<expand_component_module> method, and then installs
1142 each component into the application.
1143
1144 The C<setup_components> config option is passed to both of the above methods.
1145
1146 Installation of each component is performed by the L<setup_component> method,
1147 below.
1148
1149 =cut
1150
1151 sub setup_components {
1152     my $class = shift;
1153
1154     my $config  = $class->config->{ setup_components };
1155
1156     my @comps = sort { length $a <=> length $b }
1157                 $class->locate_components($config);
1158     my %comps = map { $_ => 1 } @comps;
1159
1160     my $deprecatedcatalyst_component_names = grep { /::[CMV]::/ } @comps;
1161     $class->log->warn(qq{Your application is using the deprecated ::[MVC]:: type naming scheme.\n}.
1162         qq{Please switch your class names to ::Model::, ::View:: and ::Controller: as appropriate.\n}
1163     ) if $deprecatedcatalyst_component_names;
1164
1165     for my $component ( @comps ) {
1166
1167         # We pass ignore_loaded here so that overlay files for (e.g.)
1168         # Model::DBI::Schema sub-classes are loaded - if it's in @comps
1169         # we know M::P::O found a file on disk so this is safe
1170
1171         Catalyst::Utils::ensure_class_loaded( $component, { ignore_loaded => 1 } );
1172
1173         # Needs to be done as soon as the component is loaded, as loading a sub-component
1174         # (next time round the loop) can cause us to get the wrong metaclass..
1175         $class->_controller_init_base_classes($component);
1176     }
1177
1178     for my $component (@comps) {
1179         $class->components->{ $component } = $class->setup_component($component);
1180         for my $component ($class->expand_component_module( $component, $config )) {
1181             next if $comps{$component};
1182             $class->_controller_init_base_classes($component); # Also cover inner packages
1183             $class->components->{ $component } = $class->setup_component($component);
1184         }
1185     }
1186 }
1187
1188 =head2 $c->locate_components( $setup_component_config )
1189
1190 This method is meant to provide a list of component modules that should be
1191 setup for the application.  By default, it will use L<Module::Pluggable>.
1192
1193 Specify a C<setup_components> config option to pass additional options directly
1194 to L<Module::Pluggable>. To add additional search paths, specify a key named
1195 C<search_extra> as an array reference. Items in the array beginning with C<::>
1196 will have the application class name prepended to them.
1197
1198 =cut
1199
1200 sub locate_components {
1201     my $class  = shift;
1202     my $config = shift;
1203
1204     my @paths   = qw( ::Controller ::C ::Model ::M ::View ::V );
1205     my $extra   = delete $config->{ search_extra } || [];
1206
1207     push @paths, @$extra;
1208
1209     my $locator = Module::Pluggable::Object->new(
1210         search_path => [ map { s/^(?=::)/$class/; $_; } @paths ],
1211         %$config
1212     );
1213
1214     my @comps = $locator->plugins;
1215
1216     return @comps;
1217 }
1218
1219 =head2 $c->expand_component_module( $component, $setup_component_config )
1220
1221 Components found by C<locate_components> will be passed to this method, which
1222 is expected to return a list of component (package) names to be set up.
1223
1224 =cut
1225
1226 sub expand_component_module {
1227     my ($class, $module) = @_;
1228     return Devel::InnerPackage::list_packages( $module );
1229 }
1230
1231 =head2 $c->setup_component
1232
1233 =cut
1234
1235 # FIXME - Ugly, ugly hack to ensure the we force initialize non-moose base classes
1236 #         nearest to Catalyst::Controller first, no matter what order stuff happens
1237 #         to be loaded. There are TODO tests in Moose for this, see
1238 #         f2391d17574eff81d911b97be15ea51080500003
1239 sub _controller_init_base_classes {
1240     my ($app_class, $component) = @_;
1241     return unless $component->isa('Catalyst::Controller');
1242     foreach my $class ( reverse @{ mro::get_linear_isa($component) } ) {
1243         Moose::Meta::Class->initialize( $class )
1244             unless find_meta($class);
1245     }
1246 }
1247
1248 sub setup_component {
1249     my( $class, $component ) = @_;
1250
1251     unless ( $component->can( 'COMPONENT' ) ) {
1252         return $component;
1253     }
1254
1255     my $suffix = Catalyst::Utils::class2classsuffix( $component );
1256     my $config = $class->config->{ $suffix } || {};
1257     # Stash catalyst_component_name in the config here, so that custom COMPONENT
1258     # methods also pass it. local to avoid pointlessly shitting in config
1259     # for the debug screen, as $component is already the key name.
1260     local $config->{catalyst_component_name} = $component;
1261
1262     my $instance = eval { $component->COMPONENT( $class, $config ); };
1263
1264     if ( my $error = $@ ) {
1265         chomp $error;
1266         Catalyst::Exception->throw(
1267             message => qq/Couldn't instantiate component "$component", "$error"/
1268         );
1269     }
1270
1271     unless (blessed $instance) {
1272         my $metaclass = Moose::Util::find_meta($component);
1273         my $method_meta = $metaclass->find_method_by_name('COMPONENT');
1274         my $component_method_from = $method_meta->associated_metaclass->name;
1275         my $value = defined($instance) ? $instance : 'undef';
1276         Catalyst::Exception->throw(
1277             message =>
1278             qq/Couldn't instantiate component "$component", COMPONENT() method (from $component_method_from) didn't return an object-like value (value was $value)./
1279         );
1280     }
1281     return $instance;
1282 }
1283
1284 =head2 $c->setup_dispatcher
1285
1286 Sets up dispatcher.
1287
1288 =cut
1289
1290 sub setup_dispatcher {
1291     my ( $class, $dispatcher ) = @_;
1292
1293     if ($dispatcher) {
1294         $dispatcher = 'Catalyst::Dispatcher::' . $dispatcher;
1295     }
1296
1297     if ( my $env = Catalyst::Utils::env_value( $class, 'DISPATCHER' ) ) {
1298         $dispatcher = 'Catalyst::Dispatcher::' . $env;
1299     }
1300
1301     unless ($dispatcher) {
1302         $dispatcher = $class->dispatcher_class;
1303     }
1304
1305     Class::MOP::load_class($dispatcher);
1306
1307     # dispatcher instance
1308     $class->dispatcher( $dispatcher->new );
1309 }
1310
1311 =head2 $c->setup_engine
1312
1313 Sets up engine.
1314
1315 =cut
1316
1317 sub setup_engine {
1318     my ( $class, $engine ) = @_;
1319
1320     if ($engine) {
1321         $engine = 'Catalyst::Engine::' . $engine;
1322     }
1323
1324     if ( my $env = Catalyst::Utils::env_value( $class, 'ENGINE' ) ) {
1325         $engine = 'Catalyst::Engine::' . $env;
1326     }
1327
1328     if ( $ENV{MOD_PERL} ) {
1329         my $meta = Class::MOP::get_metaclass_by_name($class);
1330
1331         # create the apache method
1332         $meta->add_method('apache' => sub { shift->engine->apache });
1333
1334         my ( $software, $version ) =
1335           $ENV{MOD_PERL} =~ /^(\S+)\/(\d+(?:[\.\_]\d+)+)/;
1336
1337         $version =~ s/_//g;
1338         $version =~ s/(\.[^.]+)\./$1/g;
1339
1340         if ( $software eq 'mod_perl' ) {
1341
1342             if ( !$engine ) {
1343
1344                 if ( $version >= 1.99922 ) {
1345                     $engine = 'Catalyst::Engine::Apache2::MP20';
1346                 }
1347
1348                 elsif ( $version >= 1.9901 ) {
1349                     $engine = 'Catalyst::Engine::Apache2::MP19';
1350                 }
1351
1352                 elsif ( $version >= 1.24 ) {
1353                     $engine = 'Catalyst::Engine::Apache::MP13';
1354                 }
1355
1356                 else {
1357                     Catalyst::Exception->throw( message =>
1358                           qq/Unsupported mod_perl version: $ENV{MOD_PERL}/ );
1359                 }
1360
1361             }
1362
1363             # install the correct mod_perl handler
1364             if ( $version >= 1.9901 ) {
1365                 *handler = sub  : method {
1366                     shift->handle_request(@_);
1367                 };
1368             }
1369             else {
1370                 *handler = sub ($$) { shift->handle_request(@_) };
1371             }
1372
1373         }
1374
1375         elsif ( $software eq 'Zeus-Perl' ) {
1376             $engine = 'Catalyst::Engine::Zeus';
1377         }
1378
1379         else {
1380             Catalyst::Exception->throw(
1381                 message => qq/Unsupported mod_perl: $ENV{MOD_PERL}/ );
1382         }
1383     }
1384
1385     unless ($engine) {
1386         $engine = $class->engine_class;
1387     }
1388
1389     Class::MOP::load_class($engine);
1390
1391     # check for old engines that are no longer compatible
1392     my $old_engine;
1393     if ( $engine->isa('Catalyst::Engine::Apache')
1394         && !Catalyst::Engine::Apache->VERSION )
1395     {
1396         $old_engine = 1;
1397     }
1398
1399     elsif ( $engine->isa('Catalyst::Engine::Server::Base')
1400         && Catalyst::Engine::Server->VERSION le '0.02' )
1401     {
1402         $old_engine = 1;
1403     }
1404
1405     elsif ($engine->isa('Catalyst::Engine::HTTP::POE')
1406         && $engine->VERSION eq '0.01' )
1407     {
1408         $old_engine = 1;
1409     }
1410
1411     elsif ($engine->isa('Catalyst::Engine::Zeus')
1412         && $engine->VERSION eq '0.01' )
1413     {
1414         $old_engine = 1;
1415     }
1416
1417     if ($old_engine) {
1418         Catalyst::Exception->throw( message =>
1419               qq/Engine "$engine" is not supported by this version of Catalyst/
1420         );
1421     }
1422
1423     # engine instance
1424     $class->engine( $engine->new );
1425 }
1426
1427 =head2 $c->setup_home
1428
1429 Sets up the home directory.
1430
1431 =cut
1432
1433 sub setup_home {
1434     my ( $class, $home ) = @_;
1435
1436     if ( my $env = Catalyst::Utils::env_value( $class, 'HOME' ) ) {
1437         $home = $env;
1438     }
1439
1440     $home ||= Catalyst::Utils::home($class);
1441
1442     if ($home) {
1443         #I remember recently being scolded for assigning config values like this
1444         $class->config->{home} ||= $home;
1445         $class->config->{root} ||= Path::Class::Dir->new($home)->subdir('root');
1446     }
1447 }
1448
1449 =head2 $c->setup_log
1450
1451 Sets up log by instantiating a L<Catalyst::Log|Catalyst::Log> object and
1452 passing it to C<log()>. Pass in a comma-delimited list of levels to set the
1453 log to.
1454
1455 This method also installs a C<debug> method that returns a true value into the
1456 catalyst subclass if the "debug" level is passed in the comma-delimited list,
1457 or if the C<$CATALYST_DEBUG> environment variable is set to a true value.
1458
1459 Note that if the log has already been setup, by either a previous call to
1460 C<setup_log> or by a call such as C<< __PACKAGE__->log( MyLogger->new ) >>,
1461 that this method won't actually set up the log object.
1462
1463 =cut
1464
1465 sub setup_log {
1466     my ( $class, $levels ) = @_;
1467
1468     $levels ||= '';
1469     $levels =~ s/^\s+//;
1470     $levels =~ s/\s+$//;
1471     my %levels = map { $_ => 1 } split /\s*,\s*/, $levels;
1472
1473     my $env_debug = Catalyst::Utils::env_value( $class, 'DEBUG' );
1474     if ( defined $env_debug ) {
1475         $levels{debug} = 1 if $env_debug; # Ugly!
1476         delete($levels{debug}) unless $env_debug;
1477     }
1478
1479     unless ( $class->log ) {
1480         $class->log( Catalyst::Log->new(keys %levels) );
1481     }
1482
1483     if ( $levels{debug} ) {
1484         Class::MOP::get_metaclass_by_name($class)->add_method('debug' => sub { 1 });
1485         $class->log->debug('Debug messages enabled');
1486     }
1487 }
1488
1489 =head2 $c->setup_plugins
1490
1491 Sets up plugins.
1492
1493 =cut
1494
1495 =head2 $c->setup_stats
1496
1497 Sets up timing statistics class.
1498
1499 =cut
1500
1501 sub setup_stats {
1502     my ( $class, $stats ) = @_;
1503
1504     Catalyst::Utils::ensure_class_loaded($class->stats_class);
1505
1506     my $env = Catalyst::Utils::env_value( $class, 'STATS' );
1507     if ( defined($env) ? $env : ($stats || $class->debug ) ) {
1508         Class::MOP::get_metaclass_by_name($class)->add_method('use_stats' => sub { 1 });
1509         $class->log->debug('Statistics enabled');
1510     }
1511 }
1512
1513
1514 =head2 $c->registered_plugins
1515
1516 Returns a sorted list of the plugins which have either been stated in the
1517 import list or which have been added via C<< MyApp->plugin(@args); >>.
1518
1519 If passed a given plugin name, it will report a boolean value indicating
1520 whether or not that plugin is loaded.  A fully qualified name is required if
1521 the plugin name does not begin with C<Catalyst::Plugin::>.
1522
1523  if ($c->registered_plugins('Some::Plugin')) {
1524      ...
1525  }
1526
1527 =cut
1528
1529 {
1530
1531     sub registered_plugins {
1532         my $proto = shift;
1533         return sort keys %{ $proto->_plugins } unless @_;
1534         my $plugin = shift;
1535         return 1 if exists $proto->_plugins->{$plugin};
1536         return exists $proto->_plugins->{"Catalyst::Plugin::$plugin"};
1537     }
1538
1539     sub _register_plugin {
1540         my ( $proto, $plugin, $instant ) = @_;
1541         my $class = ref $proto || $proto;
1542
1543         Class::MOP::load_class( $plugin );
1544
1545         $proto->_plugins->{$plugin} = 1;
1546         unless ($instant) {
1547             no strict 'refs';
1548             if ( my $meta = Class::MOP::get_metaclass_by_name($class) ) {
1549               my @superclasses = ($plugin, $meta->superclasses );
1550               $meta->superclasses(@superclasses);
1551             } else {
1552               unshift @{"$class\::ISA"}, $plugin;
1553             }
1554         }
1555         return $class;
1556     }
1557
1558     sub setup_plugins {
1559         my ( $class, $plugins ) = @_;
1560
1561         $class->_plugins( {} ) unless $class->_plugins;
1562         $plugins ||= [];
1563
1564         my @plugins = Catalyst::Utils::resolve_namespace($class . '::Plugin', 'Catalyst::Plugin', @$plugins);
1565
1566         for my $plugin ( reverse @plugins ) {
1567             Class::MOP::load_class($plugin);
1568             my $meta = find_meta($plugin);
1569             next if $meta && $meta->isa('Moose::Meta::Role');
1570
1571             $class->_register_plugin($plugin);
1572         }
1573
1574         my @roles =
1575             map { $_->name }
1576             grep { $_ && blessed($_) && $_->isa('Moose::Meta::Role') }
1577             map { find_meta($_) }
1578             @plugins;
1579
1580         Moose::Util::apply_all_roles(
1581             $class => @roles
1582         ) if @roles;
1583     }
1584 }
1585
1586 =head2 $c->stats_class
1587
1588 Returns or sets the stats (timing statistics) class.
1589
1590 =head2 $c->use_stats
1591
1592 Returns 1 when stats collection is enabled.  Stats collection is enabled
1593 when the -Stats options is set, debug is on or when the <MYAPP>_STATS
1594 environment variable is set.
1595
1596 Note that this is a static method, not an accessor and should be overridden
1597 by declaring C<sub use_stats { 1 }> in your MyApp.pm, not by calling C<< $c->use_stats(1) >>.
1598
1599 =cut
1600
1601 sub use_stats { 0 }
1602
1603 =head2 version
1604
1605 Returns the Catalyst version number. Mostly useful for "powered by"
1606 messages in template systems.
1607
1608 =cut
1609
1610 sub version { return $Catalyst::VERSION }
1611
1612 =head1 CONFIGURATION
1613
1614 There are a number of 'base' config variables which can be set:
1615
1616 =over
1617
1618 =item *
1619
1620 C<default_model> - The default model picked if you say C<< $c->model >>. See L</$c->model($name)>.
1621
1622 =item *
1623
1624 C<default_view> - The default view to be rendered or returned when C<< $c->view >>. See L</$c->view($name)>.
1625 is called.
1626
1627 =item *
1628
1629 C<disable_component_resolution_regex_fallback> - Turns
1630 off the deprecated component resolution functionality so
1631 that if any of the component methods (e.g. C<< $c->controller('Foo') >>)
1632 are called then regex search will not be attempted on string values and
1633 instead C<undef> will be returned.
1634
1635 =item *
1636
1637 C<home> - The application home directory. In an uninstalled application,
1638 this is the top level application directory. In an installed application,
1639 this will be the directory containing C<< MyApp.pm >>.
1640
1641 =item *
1642
1643 C<ignore_frontend_proxy> - See L</PROXY SUPPORT>
1644
1645 =item *
1646
1647 C<name> - The name of the application in debug messages and the debug and
1648 welcome screens
1649
1650 =item *
1651
1652 C<parse_on_demand> - The request body (for example file uploads) will not be parsed
1653 until it is accessed. This allows you to (for example) check authentication (and reject
1654 the upload) before actually recieving all the data. See L</ON-DEMAND PARSER>
1655
1656 =item *
1657
1658 C<root> - The root directory for templates. Usually this is just a
1659 subdirectory of the home directory, but you can set it to change the
1660 templates to a different directory.
1661
1662 =item *
1663
1664 C<search_extra> - Array reference passed to Module::Pluggable to for additional
1665 namespaces from which components will be loaded (and constructed and stored in
1666 C<< $c->components >>).
1667
1668 =item *
1669
1670 C<show_internal_actions> - If true, causes internal actions such as C<< _DISPATCH >>
1671 to be shown in hit debug tables in the test server.
1672
1673 =item *
1674
1675 C<using_frontend_proxy> - See L</PROXY SUPPORT>.
1676
1677 =back
1678
1679 =head1 INTERNAL ACTIONS
1680
1681 Catalyst uses internal actions like C<_DISPATCH>, C<_BEGIN>, C<_AUTO>,
1682 C<_ACTION>, and C<_END>. These are by default not shown in the private
1683 action table, but you can make them visible with a config parameter.
1684
1685     MyApp->config(show_internal_actions => 1);
1686
1687 =head1 ON-DEMAND PARSER
1688
1689 The request body is usually parsed at the beginning of a request,
1690 but if you want to handle input yourself, you can enable on-demand
1691 parsing with a config parameter.
1692
1693     MyApp->config(parse_on_demand => 1);
1694
1695 =head1 PROXY SUPPORT
1696
1697 Many production servers operate using the common double-server approach,
1698 with a lightweight frontend web server passing requests to a larger
1699 backend server. An application running on the backend server must deal
1700 with two problems: the remote user always appears to be C<127.0.0.1> and
1701 the server's hostname will appear to be C<localhost> regardless of the
1702 virtual host that the user connected through.
1703
1704 Catalyst will automatically detect this situation when you are running
1705 the frontend and backend servers on the same machine. The following
1706 changes are made to the request.
1707
1708     $c->req->address is set to the user's real IP address, as read from
1709     the HTTP X-Forwarded-For header.
1710
1711     The host value for $c->req->base and $c->req->uri is set to the real
1712     host, as read from the HTTP X-Forwarded-Host header.
1713
1714 Additionally, you may be running your backend application on an insecure
1715 connection (port 80) while your frontend proxy is running under SSL.  If there
1716 is a discrepancy in the ports, use the HTTP header C<X-Forwarded-Port> to
1717 tell Catalyst what port the frontend listens on.  This will allow all URIs to
1718 be created properly.
1719
1720 In the case of passing in:
1721
1722     X-Forwarded-Port: 443
1723
1724 All calls to C<uri_for> will result in an https link, as is expected.
1725
1726 Obviously, your web server must support these headers for this to work.
1727
1728 In a more complex server farm environment where you may have your
1729 frontend proxy server(s) on different machines, you will need to set a
1730 configuration option to tell Catalyst to read the proxied data from the
1731 headers.
1732
1733     MyApp->config(using_frontend_proxy => 1);
1734
1735 If you do not wish to use the proxy support at all, you may set:
1736
1737     MyApp->config(ignore_frontend_proxy => 1);
1738
1739 =head1 THREAD SAFETY
1740
1741 Catalyst has been tested under Apache 2's threading C<mpm_worker>,
1742 C<mpm_winnt>, and the standalone forking HTTP server on Windows. We
1743 believe the Catalyst core to be thread-safe.
1744
1745 If you plan to operate in a threaded environment, remember that all other
1746 modules you are using must also be thread-safe. Some modules, most notably
1747 L<DBD::SQLite>, are not thread-safe.
1748
1749 =head1 SUPPORT
1750
1751 IRC:
1752
1753     Join #catalyst on irc.perl.org.
1754
1755 Mailing Lists:
1756
1757     http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
1758     http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev
1759
1760 Web:
1761
1762     http://catalyst.perl.org
1763
1764 Wiki:
1765
1766     http://dev.catalyst.perl.org
1767
1768 =head1 SEE ALSO
1769
1770 =head2 L<Task::Catalyst> - All you need to start with Catalyst
1771
1772 =head2 L<Catalyst::Manual> - The Catalyst Manual
1773
1774 =head2 L<Catalyst::Component>, L<Catalyst::Controller> - Base classes for components
1775
1776 =head2 L<Catalyst::Engine> - Core engine
1777
1778 =head2 L<Catalyst::Log> - Log class.
1779
1780 =head2 L<Catalyst::Request> - Request object
1781
1782 =head2 L<Catalyst::Response> - Response object
1783
1784 =head2 L<Catalyst::Test> - The test suite.
1785
1786 =head1 PROJECT FOUNDER
1787
1788 sri: Sebastian Riedel <sri@cpan.org>
1789
1790 =head1 CONTRIBUTORS
1791
1792 abw: Andy Wardley
1793
1794 acme: Leon Brocard <leon@astray.com>
1795
1796 abraxxa: Alexander Hartmaier <abraxxa@cpan.org>
1797
1798 Andrew Bramble
1799
1800 Andrew Ford E<lt>A.Ford@ford-mason.co.ukE<gt>
1801
1802 Andrew Ruthven
1803
1804 andyg: Andy Grundman <andy@hybridized.org>
1805
1806 audreyt: Audrey Tang
1807
1808 bricas: Brian Cassidy <bricas@cpan.org>
1809
1810 Caelum: Rafael Kitover <rkitover@io.com>
1811
1812 chansen: Christian Hansen
1813
1814 chicks: Christopher Hicks
1815
1816 Chisel Wright C<pause@herlpacker.co.uk>
1817
1818 Danijel Milicevic C<me@danijel.de>
1819
1820 David Kamholz E<lt>dkamholz@cpan.orgE<gt>
1821
1822 David Naughton, C<naughton@umn.edu>
1823
1824 David E. Wheeler
1825
1826 dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
1827
1828 Drew Taylor
1829
1830 dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
1831
1832 esskar: Sascha Kiefer
1833
1834 fireartist: Carl Franks <cfranks@cpan.org>
1835
1836 frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
1837
1838 gabb: Danijel Milicevic
1839
1840 Gary Ashton Jones
1841
1842 Gavin Henry C<ghenry@perl.me.uk>
1843
1844 Geoff Richards
1845
1846 groditi: Guillermo Roditi <groditi@gmail.com>
1847
1848 hobbs: Andrew Rodland <andrew@cleverdomain.org>
1849
1850 ilmari: Dagfinn Ilmari MannsÃ¥ker <ilmari@ilmari.org>
1851
1852 jcamacho: Juan Camacho
1853
1854 jester: Jesse Sheidlower C<jester@panix.com>
1855
1856 jhannah: Jay Hannah <jay@jays.net>
1857
1858 Jody Belka
1859
1860 Johan Lindstrom
1861
1862 jon: Jon Schutz <jjschutz@cpan.org>
1863
1864 Jonathan Rockway C<< <jrockway@cpan.org> >>
1865
1866 Kieren Diment C<kd@totaldatasolution.com>
1867
1868 konobi: Scott McWhirter <konobi@cpan.org>
1869
1870 marcus: Marcus Ramberg <mramberg@cpan.org>
1871
1872 miyagawa: Tatsuhiko Miyagawa <miyagawa@bulknews.net>
1873
1874 mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
1875
1876 mugwump: Sam Vilain
1877
1878 naughton: David Naughton
1879
1880 ningu: David Kamholz <dkamholz@cpan.org>
1881
1882 nothingmuch: Yuval Kogman <nothingmuch@woobling.org>
1883
1884 numa: Dan Sully <daniel@cpan.org>
1885
1886 obra: Jesse Vincent
1887
1888 omega: Andreas Marienborg
1889
1890 Oleg Kostyuk <cub.uanic@gmail.com>
1891
1892 phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
1893
1894 rafl: Florian Ragwitz <rafl@debian.org>
1895
1896 random: Roland Lammel <lammel@cpan.org>
1897
1898 Robert Sedlacek C<< <rs@474.at> >>
1899
1900 sky: Arthur Bergman
1901
1902 t0m: Tomas Doran <bobtfish@bobtfish.net>
1903
1904 Ulf Edvinsson
1905
1906 Viljo Marrandi C<vilts@yahoo.com>
1907
1908 Will Hawes C<info@whawes.co.uk>
1909
1910 willert: Sebastian Willert <willert@cpan.org>
1911
1912 Yuval Kogman, C<nothingmuch@woobling.org>
1913
1914 =head1 LICENSE
1915
1916 This library is free software. You can redistribute it and/or modify it under
1917 the same terms as Perl itself.
1918
1919 =cut
1920
1921 no Moose;
1922
1923 __PACKAGE__->meta->make_immutable;
1924
1925 1;