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