make sure injected comps have the correct namespace
[catagits/Catalyst-Runtime.git] / lib / Catalyst.pm
CommitLineData
fc7ec1d9 1package Catalyst;
2
a7caa492 3use Moose;
c98492ae 4use Moose::Meta::Class ();
60eabdaf 5extends 'Catalyst::Component';
2f5cb070 6use Moose::Util qw/find_meta/;
38e43e65 7use namespace::clean -except => 'meta';
a2f2cde9 8use Catalyst::Exception;
154ef0c8 9use Catalyst::Exception::Detach;
10use Catalyst::Exception::Go;
fc7ec1d9 11use Catalyst::Log;
fbcc39ad 12use Catalyst::Request;
13use Catalyst::Request::Upload;
14use Catalyst::Response;
812a28c9 15use Catalyst::Utils;
31375184 16use Catalyst::Controller;
62b6b631 17use Data::OptList;
364d7324 18use Devel::InnerPackage ();
c50f595c 19use Module::Pluggable::Object ();
c50f595c 20use Text::SimpleTable ();
21use Path::Class::Dir ();
22use Path::Class::File ();
c50f595c 23use URI ();
933ba403 24use URI::http;
25use URI::https;
7af54927 26use HTML::Entities;
5513038d 27use Tree::Simple qw/use_weak_refs/;
28use Tree::Simple::Visitor::FindByUID;
269408a4 29use Class::C3::Adopt::NEXT;
196f06d1 30use List::MoreUtils qw/uniq/;
261c571e 31use attributes;
532f0516 32use String::RewritePrefix;
b1ededd4 33use Catalyst::EngineLoader;
5789a3d8 34use utf8;
108201b5 35use Carp qw/croak carp shortmess/;
3640641e 36use Try::Tiny;
4995a5ce 37use Safe::Isa;
dd5b1dc4 38use Moose::Util 'find_meta';
ad79be34 39use Plack::Middleware::Conditional;
40use Plack::Middleware::ReverseProxy;
fb99321f 41use Plack::Middleware::IIS6ScriptNameFix;
201e0a1f 42use Plack::Middleware::IIS7KeepAliveFix;
d3670826 43use Plack::Middleware::LighttpdScriptNameFix;
aa20e9f5 44use Plack::Middleware::ContentLength;
45use Plack::Middleware::Head;
660f9bb0 46use Plack::Middleware::HTTPExceptions;
ecf903d0 47use Plack::Middleware::FixMissingBodyInRedirect;
3157d22a 48use Plack::Middleware::MethodOverride;
79070bc6 49use Plack::Middleware::RemoveRedundantBody;
6561feae 50use Catalyst::Middleware::Stash;
20a09634 51use Plack::Util;
e7399d8b 52use Class::Load 'load_class';
0ca510f0 53use Encode 2.21 'decode_utf8', 'encode_utf8';
fc7ec1d9 54
0f6be50c 55BEGIN { require 5.008003; }
f63c03e4 56
8a440eba 57has stack => (is => 'ro', default => sub { [] });
6680c772 58has state => (is => 'rw', default => 0);
b6d4ee6e 59has stats => (is => 'rw');
60has action => (is => 'rw');
6680c772 61has counter => (is => 'rw', default => sub { {} });
398f13db 62has request => (
63 is => 'rw',
64 default => sub {
65 my $self = shift;
ec4d7259 66 my $class = ref $self;
67 my $composed_request_class = $class->composed_request_class;
68 return $composed_request_class->new( $self->_build_request_constructor_args);
398f13db 69 },
70 lazy => 1,
71);
a2c6c7b9 72sub _build_request_constructor_args {
0df490ef 73 my $self = shift;
74 my %p = ( _log => $self->log );
75 $p{_uploadtmp} = $self->_uploadtmp if $self->_has_uploadtmp;
b87d834e 76 $p{data_handlers} = {$self->registered_data_handlers};
88ba7793 77 $p{_use_hash_multivalue} = $self->config->{use_hash_multivalue_in_request}
78 if $self->config->{use_hash_multivalue_in_request};
0df490ef 79 \%p;
80}
81
ec4d7259 82sub composed_request_class {
83 my $class = shift;
044e7667 84 my @traits = (@{$class->request_class_traits||[]}, @{$class->config->{request_class_traits}||[]});
ec4d7259 85 return $class->_composed_request_class ||
044e7667 86 $class->_composed_request_class(Moose::Util::with_traits($class->request_class, @traits));
ec4d7259 87}
88
7c1c4dc6 89has response => (
90 is => 'rw',
91 default => sub {
92 my $self = shift;
ec4d7259 93 my $class = ref $self;
94 my $composed_response_class = $class->composed_response_class;
95 return $composed_response_class->new( $self->_build_response_constructor_args);
7c1c4dc6 96 },
97 lazy => 1,
98);
a2c6c7b9 99sub _build_response_constructor_args {
e8361cf8 100 return +{
101 _log => $_[0]->log,
102 encoding => $_[0]->encoding,
103 };
0df490ef 104}
105
ec4d7259 106sub composed_response_class {
107 my $class = shift;
044e7667 108 my @traits = (@{$class->response_class_traits||[]}, @{$class->config->{response_class_traits}||[]});
ec4d7259 109 return $class->_composed_response_class ||
044e7667 110 $class->_composed_response_class(Moose::Util::with_traits($class->response_class, @traits));
ec4d7259 111}
112
e63bdf38 113has namespace => (is => 'rw');
114
8767c5a3 115sub depth { scalar @{ shift->stack || [] }; }
0fc2d522 116sub comp { shift->component(@_) }
6680c772 117
118sub req {
6680c772 119 my $self = shift; return $self->request(@_);
120}
121sub res {
6680c772 122 my $self = shift; return $self->response(@_);
123}
fbcc39ad 124
125# For backwards compatibility
0fc2d522 126sub finalize_output { shift->finalize_body(@_) };
fbcc39ad 127
128# For statistics
129our $COUNT = 1;
130our $START = time;
131our $RECURSION = 1000;
154ef0c8 132our $DETACH = Catalyst::Exception::Detach->new;
133our $GO = Catalyst::Exception::Go->new;
fbcc39ad 134
b6d4ee6e 135#I imagine that very few of these really need to be class variables. if any.
136#maybe we should just make them attributes with a default?
fbcc39ad 137__PACKAGE__->mk_classdata($_)
3cec521a 138 for qw/components arguments dispatcher engine log dispatcher_class
1e5dad00 139 engine_loader context_class request_class response_class stats_class
b87d834e 140 setup_finished _psgi_app loading_psgi_file run_options _psgi_middleware
ec4d7259 141 _data_handlers _encoding _encode_check finalized_default_middleware
142 request_class_traits response_class_traits stats_class_traits
143 _composed_request_class _composed_response_class _composed_stats_class/;
cb0354c6 144
3cec521a 145__PACKAGE__->dispatcher_class('Catalyst::Dispatcher');
3cec521a 146__PACKAGE__->request_class('Catalyst::Request');
147__PACKAGE__->response_class('Catalyst::Response');
dc5f035e 148__PACKAGE__->stats_class('Catalyst::Stats');
ec4d7259 149
150sub composed_stats_class {
151 my $class = shift;
044e7667 152 my @traits = (@{$class->stats_class_traits||[]}, @{$class->config->{stats_class_traits}||[]});
ec4d7259 153 return $class->_composed_stats_class ||
044e7667 154 $class->_composed_stats_class(Moose::Util::with_traits($class->stats_class, @traits));
ec4d7259 155}
156
9c38cb50 157__PACKAGE__->_encode_check(Encode::FB_CROAK | Encode::LEAVE_SRC);
fbcc39ad 158
6415bb4d 159# Remember to update this in Catalyst::Runtime as well!
a31cd019 160our $VERSION = '5.90091';
5c779e98 161$VERSION = eval $VERSION if $VERSION =~ /_/; # numify for warning-free dev releases
189e2a51 162
fbcc39ad 163sub import {
164 my ( $class, @arguments ) = @_;
165
166 # We have to limit $class to Catalyst to avoid pushing Catalyst upon every
167 # callers @ISA.
168 return unless $class eq 'Catalyst';
169
84ff88cf 170 my $caller = caller();
171 return if $caller eq 'main';
269408a4 172
84ff88cf 173 my $meta = Moose::Meta::Class->initialize($caller);
fbcc39ad 174 unless ( $caller->isa('Catalyst') ) {
84ff88cf 175 my @superclasses = ($meta->superclasses, $class, 'Catalyst::Controller');
176 $meta->superclasses(@superclasses);
177 }
1cad29ab 178 # Avoid possible C3 issues if 'Moose::Object' is already on RHS of MyApp
179 $meta->superclasses(grep { $_ ne 'Moose::Object' } $meta->superclasses);
180
84ff88cf 181 unless( $meta->has_method('meta') ){
9c74923d 182 if ($Moose::VERSION >= 1.15) {
183 $meta->_add_meta_method('meta');
184 }
185 else {
186 $meta->add_method(meta => sub { Moose::Meta::Class->initialize("${caller}") } );
187 }
fbcc39ad 188 }
189
190 $caller->arguments( [@arguments] );
191 $caller->setup_home;
192}
fc7ec1d9 193
e6bfaa20 194sub _application { $_[0] }
195
bf590d36 196=encoding UTF-8
197
fc7ec1d9 198=head1 NAME
199
200Catalyst - The Elegant MVC Web Application Framework
201
9e7f288e 202=for html
203<a href="https://badge.fury.io/pl/Catalyst-Runtime"><img src="https://badge.fury.io/pl/Catalyst-Runtime.svg" alt="CPAN version" height="18"></a>
204<a href="https://travis-ci.org/perl-catalyst/catalyst-runtime/"><img src="https://api.travis-ci.org/perl-catalyst/catalyst-runtime.png" alt="Catalyst></a>
205<a href="http://cpants.cpanauthors.org/dist/Catalyst-Runtime"><img src="http://cpants.cpanauthors.org/dist/Catalyst-Runtime.png" alt='Kwalitee Score' /></a>
206
fc7ec1d9 207=head1 SYNOPSIS
208
e7ad3b81 209See the L<Catalyst::Manual> distribution for comprehensive
210documentation and tutorials.
211
86418559 212 # Install Catalyst::Devel for helpers and other development tools
b4b01a8a 213 # use the helper to create a new application
91864987 214 catalyst.pl MyApp
fc7ec1d9 215
216 # add models, views, controllers
2f381252 217 script/myapp_create.pl model MyDatabase DBIC::Schema create=static dbi:SQLite:/path/to/db
cc95842f 218 script/myapp_create.pl view MyTemplate TT
0ef52a96 219 script/myapp_create.pl controller Search
fc7ec1d9 220
e7f1cf73 221 # built in testserver -- use -r to restart automatically on changes
cc95842f 222 # --help to see all available options
ae4e40a7 223 script/myapp_server.pl
fc7ec1d9 224
0ef52a96 225 # command line testing interface
ae4e40a7 226 script/myapp_test.pl /yada
fc7ec1d9 227
b4b01a8a 228 ### in lib/MyApp.pm
0ef52a96 229 use Catalyst qw/-Debug/; # include plugins here as well
62a6df80 230
85d9fce6 231 ### In lib/MyApp/Controller/Root.pm (autocreated)
20f0d47b 232 sub foo : Chained('/') Args() { # called for /foo, /foo/1, /foo/1/2, etc.
ae1e6b59 233 my ( $self, $c, @args ) = @_; # args are qw/1 2/ for /foo/1/2
234 $c->stash->{template} = 'foo.tt'; # set the template
0ef52a96 235 # lookup something from db -- stash vars are passed to TT
62a6df80 236 $c->stash->{data} =
b4b01a8a 237 $c->model('Database::Foo')->search( { country => $args[0] } );
0ef52a96 238 if ( $c->req->params->{bar} ) { # access GET or POST parameters
239 $c->forward( 'bar' ); # process another action
62a6df80 240 # do something else after forward returns
0ef52a96 241 }
242 }
62a6df80 243
ae1e6b59 244 # The foo.tt TT template can use the stash data from the database
0ef52a96 245 [% WHILE (item = data.next) %]
246 [% item.foo %]
247 [% END %]
62a6df80 248
0ef52a96 249 # called for /bar/of/soap, /bar/of/soap/10, etc.
20f0d47b 250 sub bar : Chained('/') PathPart('/bar/of/soap') Args() { ... }
62a6df80 251
ae1e6b59 252 # called after all actions are finished
20f0d47b 253 sub end : Action {
5a8ed4fe 254 my ( $self, $c ) = @_;
0ef52a96 255 if ( scalar @{ $c->error } ) { ... } # handle errors
256 return if $c->res->body; # already have a response
257 $c->forward( 'MyApp::View::TT' ); # render template
5a8ed4fe 258 }
259
0ef52a96 260See L<Catalyst::Manual::Intro> for additional information.
3803e98f 261
fc7ec1d9 262=head1 DESCRIPTION
263
86418559 264Catalyst is a modern framework for making web applications without the
265pain usually associated with this process. This document is a reference
266to the main Catalyst application. If you are a new user, we suggest you
267start with L<Catalyst::Manual::Tutorial> or L<Catalyst::Manual::Intro>.
fc7ec1d9 268
269See L<Catalyst::Manual> for more documentation.
270
ae1e6b59 271Catalyst plugins can be loaded by naming them as arguments to the "use
272Catalyst" statement. Omit the C<Catalyst::Plugin::> prefix from the
273plugin name, i.e., C<Catalyst::Plugin::My::Module> becomes
274C<My::Module>.
fc7ec1d9 275
0ef52a96 276 use Catalyst qw/My::Module/;
fc7ec1d9 277
836e1134 278If your plugin starts with a name other than C<Catalyst::Plugin::>, you can
279fully qualify the name by using a unary plus:
280
281 use Catalyst qw/
282 My::Module
283 +Fully::Qualified::Plugin::Name
284 /;
285
5853fd49 286Special flags like C<-Debug> can also be specified as
ae1e6b59 287arguments when Catalyst is loaded:
fc7ec1d9 288
289 use Catalyst qw/-Debug My::Module/;
290
ae1e6b59 291The position of plugins and flags in the chain is important, because
86418559 292they are loaded in the order in which they appear.
fc7ec1d9 293
23f9d934 294The following flags are supported:
295
b5ecfcf0 296=head2 -Debug
23f9d934 297
f8ad6ea5 298Enables debug output. You can also force this setting from the system
86418559 299environment with CATALYST_DEBUG or <MYAPP>_DEBUG. The environment
300settings override the application, with <MYAPP>_DEBUG having the highest
301priority.
fc7ec1d9 302
c8083f4e 303This sets the log level to 'debug' and enables full debug output on the
304error screen. If you only want the latter, see L<< $c->debug >>.
305
b5ecfcf0 306=head2 -Home
fbcc39ad 307
ae1e6b59 308Forces Catalyst to use a specific home directory, e.g.:
309
86418559 310 use Catalyst qw[-Home=/usr/mst];
fbcc39ad 311
cc95842f 312This can also be done in the shell environment by setting either the
313C<CATALYST_HOME> environment variable or C<MYAPP_HOME>; where C<MYAPP>
314is replaced with the uppercased name of your application, any "::" in
315the name will be replaced with underscores, e.g. MyApp::Web should use
316MYAPP_WEB_HOME. If both variables are set, the MYAPP_HOME one will be used.
317
d7a82605 318If none of these are set, Catalyst will attempt to automatically detect the
8ad6fd58 319home directory. If you are working in a development environment, Catalyst
a943d722 320will try and find the directory containing either Makefile.PL, Build.PL,
321dist.ini, or cpanfile. If the application has been installed into the system
322(i.e. you have done C<make install>), then Catalyst will use the path to your
8ad6fd58 323application module, without the .pm extension (e.g., /foo/MyApp if your
d7a82605 324application was installed at /foo/MyApp.pm)
325
b5ecfcf0 326=head2 -Log
fbcc39ad 327
0fa676a7 328 use Catalyst '-Log=warn,fatal,error';
62a6df80 329
0fa676a7 330Specifies a comma-delimited list of log levels.
fbcc39ad 331
dc5f035e 332=head2 -Stats
333
01c5eab0 334Enables statistics collection and reporting.
dc5f035e 335
01c5eab0 336 use Catalyst qw/-Stats=1/;
dc5f035e 337
01c5eab0 338You can also force this setting from the system environment with CATALYST_STATS
339or <MYAPP>_STATS. The environment settings override the application, with
340<MYAPP>_STATS having the highest priority.
dc5f035e 341
01c5eab0 342Stats are also enabled if L<< debugging |/"-Debug" >> is enabled.
dc5f035e 343
23f9d934 344=head1 METHODS
345
f7b672ef 346=head2 INFORMATION ABOUT THE CURRENT REQUEST
0ef52a96 347
b5ecfcf0 348=head2 $c->action
66e28e3f 349
ae1e6b59 350Returns a L<Catalyst::Action> object for the current action, which
351stringifies to the action name. See L<Catalyst::Action>.
0ef52a96 352
b5ecfcf0 353=head2 $c->namespace
0ef52a96 354
86418559 355Returns the namespace of the current action, i.e., the URI prefix
ae1e6b59 356corresponding to the controller of the current action. For example:
357
358 # in Controller::Foo::Bar
359 $c->namespace; # returns 'foo/bar';
0ef52a96 360
b5ecfcf0 361=head2 $c->request
0ef52a96 362
b5ecfcf0 363=head2 $c->req
0ef52a96 364
86418559 365Returns the current L<Catalyst::Request> object, giving access to
366information about the current client request (including parameters,
367cookies, HTTP headers, etc.). See L<Catalyst::Request>.
0ef52a96 368
b4b01a8a 369=head2 REQUEST FLOW HANDLING
0ef52a96 370
b5ecfcf0 371=head2 $c->forward( $action [, \@arguments ] )
0ef52a96 372
b5ecfcf0 373=head2 $c->forward( $class, $method, [, \@arguments ] )
0ef52a96 374
52c77837 375This is one way of calling another action (method) in the same or
376a different controller. You can also use C<< $self->my_method($c, @args) >>
377in the same controller or C<< $c->controller('MyController')->my_method($c, @args) >>
378in a different controller.
379The main difference is that 'forward' uses some of the Catalyst request
380cycle overhead, including debugging, which may be useful to you. On the
381other hand, there are some complications to using 'forward', restrictions
382on values returned from 'forward', and it may not handle errors as you prefer.
383Whether you use 'forward' or not is up to you; it is not considered superior to
384the other ways to call a method.
385
386'forward' calls another action, by its private name. If you give a
b4b01a8a 387class name but no method, C<process()> is called. You may also optionally
388pass arguments in an arrayref. The action will receive the arguments in
cc95842f 389C<@_> and C<< $c->req->args >>. Upon returning from the function,
390C<< $c->req->args >> will be restored to the previous values.
0ef52a96 391
3b984c64 392Any data C<return>ed from the action forwarded to, will be returned by the
d759db1e 393call to forward.
3b984c64 394
395 my $foodata = $c->forward('/foo');
0ef52a96 396 $c->forward('index');
1d3a0700 397 $c->forward(qw/Model::DBIC::Foo do_stuff/);
398 $c->forward('View::TT');
0ef52a96 399
18a9655c 400Note that L<< forward|/"$c->forward( $action [, \@arguments ] )" >> implies
401an C<< eval { } >> around the call (actually
8ad6fd58 402L<< execute|/"$c->execute( $class, $coderef )" >> does), thus rendering all
403exceptions thrown by the called action non-fatal and pushing them onto
404$c->error instead. If you want C<die> to propagate you need to do something
405like:
f3e6a8c0 406
407 $c->forward('foo');
7d6820cc 408 die join "\n", @{ $c->error } if @{ $c->error };
f3e6a8c0 409
86418559 410Or make sure to always return true values from your actions and write
411your code like this:
f3e6a8c0 412
413 $c->forward('foo') || return;
1d3a0700 414
2e60292e 415Another note is that C<< $c->forward >> always returns a scalar because it
416actually returns $c->state which operates in a scalar context.
417Thus, something like:
418
419 return @array;
1d3a0700 420
421in an action that is forwarded to is going to return a scalar,
2e60292e 422i.e. how many items are in that array, which is probably not what you want.
1d3a0700 423If you need to return an array then return a reference to it,
2e60292e 424or stash it like so:
425
426 $c->stash->{array} = \@array;
427
428and access it from the stash.
f3e6a8c0 429
9c74923d 430Keep in mind that the C<end> method used is that of the caller action. So a C<$c-E<gt>detach> inside a forwarded action would run the C<end> method from the original action requested.
431
0ef52a96 432=cut
433
6680c772 434sub forward { my $c = shift; no warnings 'recursion'; $c->dispatcher->forward( $c, @_ ) }
0ef52a96 435
b5ecfcf0 436=head2 $c->detach( $action [, \@arguments ] )
0ef52a96 437
b5ecfcf0 438=head2 $c->detach( $class, $method, [, \@arguments ] )
0ef52a96 439
264bac8c 440=head2 $c->detach()
441
18a9655c 442The same as L<< forward|/"$c->forward( $action [, \@arguments ] )" >>, but
443doesn't return to the previous action when processing is finished.
0ef52a96 444
264bac8c 445When called with no arguments it escapes the processing chain entirely.
446
0ef52a96 447=cut
448
449sub detach { my $c = shift; $c->dispatcher->detach( $c, @_ ) }
450
8431b9cc 451=head2 $c->visit( $action [, \@arguments ] )
452
5d91ffe2 453=head2 $c->visit( $action [, \@captures, \@arguments ] )
ae0e35ee 454
8431b9cc 455=head2 $c->visit( $class, $method, [, \@arguments ] )
456
5d91ffe2 457=head2 $c->visit( $class, $method, [, \@captures, \@arguments ] )
ae0e35ee 458
18a9655c 459Almost the same as L<< forward|/"$c->forward( $action [, \@arguments ] )" >>,
460but does a full dispatch, instead of just calling the new C<$action> /
461C<< $class->$method >>. This means that C<begin>, C<auto> and the method
462you go to are called, just like a new request.
ae0e35ee 463
4b48773e 464In addition both C<< $c->action >> and C<< $c->namespace >> are localized.
18a9655c 465This means, for example, that C<< $c->action >> methods such as
466L<name|Catalyst::Action/name>, L<class|Catalyst::Action/class> and
467L<reverse|Catalyst::Action/reverse> return information for the visited action
468when they are invoked within the visited action. This is different from the
469behavior of L<< forward|/"$c->forward( $action [, \@arguments ] )" >>, which
470continues to use the $c->action object from the caller action even when
8ad6fd58 471invoked from the called action.
4b48773e 472
18a9655c 473C<< $c->stash >> is kept unchanged.
ae0e35ee 474
18a9655c 475In effect, L<< visit|/"$c->visit( $action [, \@captures, \@arguments ] )" >>
476allows you to "wrap" another action, just as it would have been called by
477dispatching from a URL, while the analogous
478L<< go|/"$c->go( $action [, \@captures, \@arguments ] )" >> allows you to
479transfer control to another action as if it had been reached directly from a URL.
ae0e35ee 480
481=cut
482
483sub visit { my $c = shift; $c->dispatcher->visit( $c, @_ ) }
484
8431b9cc 485=head2 $c->go( $action [, \@arguments ] )
486
5d91ffe2 487=head2 $c->go( $action [, \@captures, \@arguments ] )
2f381252 488
8431b9cc 489=head2 $c->go( $class, $method, [, \@arguments ] )
490
5d91ffe2 491=head2 $c->go( $class, $method, [, \@captures, \@arguments ] )
2f381252 492
1d3a0700 493The relationship between C<go> and
12c48597 494L<< visit|/"$c->visit( $action [, \@captures, \@arguments ] )" >> is the same as
1d3a0700 495the relationship between
12c48597 496L<< forward|/"$c->forward( $class, $method, [, \@arguments ] )" >> and
497L<< detach|/"$c->detach( $action [, \@arguments ] )" >>. Like C<< $c->visit >>,
498C<< $c->go >> will perform a full dispatch on the specified action or method,
499with localized C<< $c->action >> and C<< $c->namespace >>. Like C<detach>,
500C<go> escapes the processing of the current request chain on completion, and
98d049ef 501does not return to its cunless blessed $cunless blessed $caller.
2f381252 502
9c74923d 503@arguments are arguments to the final destination of $action. @captures are
504arguments to the intermediate steps, if any, on the way to the final sub of
505$action.
506
2f381252 507=cut
508
509sub go { my $c = shift; $c->dispatcher->go( $c, @_ ) }
510
b4b01a8a 511=head2 $c->response
512
513=head2 $c->res
514
cc95842f 515Returns the current L<Catalyst::Response> object, see there for details.
b4b01a8a 516
517=head2 $c->stash
518
519Returns a hashref to the stash, which may be used to store data and pass
520it between components during a request. You can also set hash keys by
521passing arguments. The stash is automatically sent to the view. The
522stash is cleared at the end of a request; it cannot be used for
86418559 523persistent storage (for this you must use a session; see
524L<Catalyst::Plugin::Session> for a complete system integrated with
525Catalyst).
b4b01a8a 526
527 $c->stash->{foo} = $bar;
528 $c->stash( { moose => 'majestic', qux => 0 } );
529 $c->stash( bar => 1, gorch => 2 ); # equivalent to passing a hashref
62a6df80 530
b4b01a8a 531 # stash is automatically passed to the view for use in a template
cc95842f 532 $c->forward( 'MyApp::View::TT' );
b4b01a8a 533
4b0b7489 534The stash hash is currently stored in the PSGI C<$env> and is managed by
535L<Catalyst::Middleware::Stash>. Since it's part of the C<$env> items in
536the stash can be accessed in sub applications mounted under your main
537L<Catalyst> application. For example if you delegate the response of an
538action to another L<Catalyst> application, that sub application will have
539access to all the stash keys of the main one, and if can of course add
540more keys of its own. However those new keys will not 'bubble' back up
541to the main application.
542
543For more information the best thing to do is to review the test case:
544t/middleware-stash.t in the distribution /t directory.
545
6561feae 546=cut
547
548sub stash {
549 my $c = shift;
98d049ef 550 $c->log->error("You are requesting the stash but you don't have a context") unless blessed $c;
561098d1 551 return Catalyst::Middleware::Stash::get_stash($c->req->env)->(@_);
6561feae 552}
b4b01a8a 553
b5ecfcf0 554=head2 $c->error
0ef52a96 555
b5ecfcf0 556=head2 $c->error($error, ...)
0ef52a96 557
b5ecfcf0 558=head2 $c->error($arrayref)
0ef52a96 559
83a8fcac 560Returns an arrayref containing error messages. If Catalyst encounters an
561error while processing a request, it stores the error in $c->error. This
e7ad3b81 562method should only be used to store fatal error messages.
0ef52a96 563
564 my @error = @{ $c->error };
565
566Add a new error.
567
568 $c->error('Something bad happened');
569
b94f8e72 570Calling this will always return an arrayref (if there are no errors it
571will be an empty arrayref.
572
0ef52a96 573=cut
574
575sub error {
576 my $c = shift;
577 if ( $_[0] ) {
578 my $error = ref $_[0] eq 'ARRAY' ? $_[0] : [@_];
9ce44430 579 croak @$error unless ref $c;
0ef52a96 580 push @{ $c->{error} }, @$error;
581 }
582 elsif ( defined $_[0] ) { $c->{error} = undef }
583 return $c->{error} || [];
584}
585
b4b01a8a 586
587=head2 $c->state
588
1d3a0700 589Contains the return value of the last executed action.
2e60292e 590Note that << $c->state >> operates in a scalar context which means that all
591values it returns are scalar.
b4b01a8a 592
ca81eb67 593=head2 $c->clear_errors
594
595Clear errors. You probably don't want to clear the errors unless you are
596implementing a custom error screen.
597
598This is equivalent to running
599
600 $c->error(0);
601
602=cut
603
604sub clear_errors {
605 my $c = shift;
606 $c->error(0);
607}
608
30e84ba1 609=head2 $c->has_errors
610
611Returns true if you have errors
612
613=cut
614
615sub has_errors { scalar(@{shift->error}) ? 1:0 }
616
b94f8e72 617=head2 $c->last_error
618
619Returns the most recent error in the stack (the one most recently added...)
620or nothing if there are no errors.
621
622=cut
623
624sub last_error { my ($err, @errs) = @{shift->error}; return $err }
625
626=head2 shift_errors
627
628shifts the most recently added error off the error stack and returns if. Returns
566678d0 629nothing if there are no more errors.
b94f8e72 630
631=cut
632
633sub shift_errors {
634 my ($self) = @_;
635 my ($err, @errors) = @{$self->error};
636 $self->{error} = \@errors;
637 return $err;
638}
639
2f381252 640sub _comp_search_prefixes {
c23b894b 641 my $c = shift;
642 return map $c->components->{ $_ }, $c->_comp_names_search_prefixes(@_);
643}
644
645# search components given a name and some prefixes
646sub _comp_names_search_prefixes {
2f381252 647 my ( $c, $name, @prefixes ) = @_;
648 my $appclass = ref $c || $c;
649 my $filter = "^${appclass}::(" . join( '|', @prefixes ) . ')::';
cce626ed 650 $filter = qr/$filter/; # Compile regex now rather than once per loop
0ef52a96 651
2f381252 652 # map the original component name to the sub part that we will search against
653 my %eligible = map { my $n = $_; $n =~ s{^$appclass\::[^:]+::}{}; $_ => $n; }
654 grep { /$filter/ } keys %{ $c->components };
0756fe3b 655
2f381252 656 # undef for a name will return all
657 return keys %eligible if !defined $name;
0756fe3b 658
4995a5ce 659 my $query = $name->$_isa('Regexp') ? $name : qr/^$name$/i;
2f381252 660 my @result = grep { $eligible{$_} =~ m{$query} } keys %eligible;
0756fe3b 661
c23b894b 662 return @result if @result;
0756fe3b 663
2f381252 664 # if we were given a regexp to search against, we're done.
4995a5ce 665 return if $name->$_isa('Regexp');
0756fe3b 666
ab86b480 667 # skip regexp fallback if configured
668 return
669 if $appclass->config->{disable_component_resolution_regex_fallback};
670
2f381252 671 # regexp fallback
672 $query = qr/$name/i;
c23b894b 673 @result = grep { $eligible{ $_ } =~ m{$query} } keys %eligible;
0756fe3b 674
2f381252 675 # no results? try against full names
676 if( !@result ) {
c23b894b 677 @result = grep { m{$query} } keys %eligible;
2f381252 678 }
0756fe3b 679
2f381252 680 # don't warn if we didn't find any results, it just might not exist
681 if( @result ) {
cce626ed 682 # Disgusting hack to work out correct method name
683 my $warn_for = lc $prefixes[0];
e260802a 684 my $msg = "Used regexp fallback for \$c->${warn_for}('${name}'), which found '" .
108201b5 685 (join '", "', @result) . "'. Relying on regexp fallback behavior for " .
686 "component resolution is unreliable and unsafe.";
687 my $short = $result[0];
ab86b480 688 # remove the component namespace prefix
689 $short =~ s/.*?(Model|Controller|View):://;
108201b5 690 my $shortmess = Carp::shortmess('');
691 if ($shortmess =~ m#Catalyst/Plugin#) {
692 $msg .= " You probably need to set '$short' instead of '${name}' in this " .
693 "plugin's config";
694 } elsif ($shortmess =~ m#Catalyst/lib/(View|Controller)#) {
695 $msg .= " You probably need to set '$short' instead of '${name}' in this " .
696 "component's config";
697 } else {
ab86b480 698 $msg .= " You probably meant \$c->${warn_for}('$short') instead of \$c->${warn_for}('${name}'), " .
108201b5 699 "but if you really wanted to search, pass in a regexp as the argument " .
cce626ed 700 "like so: \$c->${warn_for}(qr/${name}/)";
108201b5 701 }
702 $c->log->warn( "${msg}$shortmess" );
2f381252 703 }
0756fe3b 704
2f381252 705 return @result;
0756fe3b 706}
707
62a6df80 708# Find possible names for a prefix
3b88a455 709sub _comp_names {
710 my ( $c, @prefixes ) = @_;
3b88a455 711 my $appclass = ref $c || $c;
712
2f381252 713 my $filter = "^${appclass}::(" . join( '|', @prefixes ) . ')::';
3b88a455 714
c23b894b 715 my @names = map { s{$filter}{}; $_; }
716 $c->_comp_names_search_prefixes( undef, @prefixes );
717
3b88a455 718 return @names;
719}
720
197bd788 721# Filter a component before returning by calling ACCEPT_CONTEXT if available
e39312ba 722
197bd788 723sub _filter_component {
724 my ( $c, $comp, @args ) = @_;
2f381252 725
3e560748 726 if(ref $comp eq 'CODE') {
98d049ef 727 $comp = $comp->();
3e560748 728 }
729
8abaac85 730 if ( eval { $comp->can('ACCEPT_CONTEXT'); } ) {
718a1619 731 return $comp->ACCEPT_CONTEXT( $c, @args );
197bd788 732 }
62a6df80 733
3e560748 734 $c->log->warn("You called component '${\$comp->catalyst_component_name}' with arguments [@args], but this component does not ACCEPT_CONTEXT, so args are ignored.") if scalar(@args) && $c->debug;
735
2f381252 736 return $comp;
197bd788 737}
738
f7b672ef 739=head2 COMPONENT ACCESSORS
0ef52a96 740
b5ecfcf0 741=head2 $c->controller($name)
af3ff00e 742
0ef52a96 743Gets a L<Catalyst::Controller> instance by name.
af3ff00e 744
745 $c->controller('Foo')->do_stuff;
746
86418559 747If the name is omitted, will return the controller for the dispatched
748action.
649fd1fa 749
2f381252 750If you want to search for controllers, pass in a regexp as the argument.
751
752 # find all controllers that start with Foo
753 my @foo_controllers = $c->controller(qr{^Foo});
754
755
af3ff00e 756=cut
757
758sub controller {
197bd788 759 my ( $c, $name, @args ) = @_;
2f381252 760
13311c16 761 my $appclass = ref($c) || $c;
2f381252 762 if( $name ) {
4995a5ce 763 unless ( $name->$_isa('Regexp') ) { # Direct component hash lookup to avoid costly regexps
13311c16 764 my $comps = $c->components;
765 my $check = $appclass."::Controller::".$name;
766 return $c->_filter_component( $comps->{$check}, @args ) if exists $comps->{$check};
767 }
2f381252 768 my @result = $c->_comp_search_prefixes( $name, qw/Controller C/ );
769 return map { $c->_filter_component( $_, @args ) } @result if ref $name;
770 return $c->_filter_component( $result[ 0 ], @args );
771 }
772
197bd788 773 return $c->component( $c->action->class );
af3ff00e 774}
775
b5ecfcf0 776=head2 $c->model($name)
fc7ec1d9 777
0ef52a96 778Gets a L<Catalyst::Model> instance by name.
779
780 $c->model('Foo')->do_stuff;
fc7ec1d9 781
3e560748 782Any extra arguments are directly passed to ACCEPT_CONTEXT, if the model
783defines ACCEPT_CONTEXT. If it does not, the args are discarded.
72f87c4b 784
62a6df80 785If the name is omitted, it will look for
2f381252 786 - a model object in $c->stash->{current_model_instance}, then
a3b71f0f 787 - a model name in $c->stash->{current_model}, then
788 - a config setting 'default_model', or
789 - check if there is only one model, and return it if that's the case.
649fd1fa 790
2f381252 791If you want to search for models, pass in a regexp as the argument.
792
793 # find all models that start with Foo
794 my @foo_models = $c->model(qr{^Foo});
795
fc7ec1d9 796=cut
797
0ef52a96 798sub model {
197bd788 799 my ( $c, $name, @args ) = @_;
df960201 800 my $appclass = ref($c) || $c;
2f381252 801 if( $name ) {
4995a5ce 802 unless ( $name->$_isa('Regexp') ) { # Direct component hash lookup to avoid costly regexps
13311c16 803 my $comps = $c->components;
804 my $check = $appclass."::Model::".$name;
805 return $c->_filter_component( $comps->{$check}, @args ) if exists $comps->{$check};
806 }
2f381252 807 my @result = $c->_comp_search_prefixes( $name, qw/Model M/ );
808 return map { $c->_filter_component( $_, @args ) } @result if ref $name;
809 return $c->_filter_component( $result[ 0 ], @args );
810 }
811
a3b71f0f 812 if (ref $c) {
62a6df80 813 return $c->stash->{current_model_instance}
a3b71f0f 814 if $c->stash->{current_model_instance};
815 return $c->model( $c->stash->{current_model} )
816 if $c->stash->{current_model};
a3b71f0f 817 }
df960201 818 return $c->model( $appclass->config->{default_model} )
819 if $appclass->config->{default_model};
3b88a455 820
2f381252 821 my( $comp, $rest ) = $c->_comp_search_prefixes( undef, qw/Model M/);
3b88a455 822
2f381252 823 if( $rest ) {
108201b5 824 $c->log->warn( Carp::shortmess('Calling $c->model() will return a random model unless you specify one of:') );
4600a5a1 825 $c->log->warn( '* $c->config(default_model => "the name of the default model to use")' );
2f381252 826 $c->log->warn( '* $c->stash->{current_model} # the name of the model to use for this request' );
827 $c->log->warn( '* $c->stash->{current_model_instance} # the instance of the model to use for this request' );
11c270bd 828 $c->log->warn( 'NB: in version 5.81, the "random" behavior will not work at all.' );
2f381252 829 }
3b88a455 830
2f381252 831 return $c->_filter_component( $comp );
3b88a455 832}
833
b4b01a8a 834
b5ecfcf0 835=head2 $c->view($name)
0ef52a96 836
837Gets a L<Catalyst::View> instance by name.
fc7ec1d9 838
0ef52a96 839 $c->view('Foo')->do_stuff;
fc7ec1d9 840
72f87c4b 841Any extra arguments are directly passed to ACCEPT_CONTEXT.
842
62a6df80 843If the name is omitted, it will look for
2f381252 844 - a view object in $c->stash->{current_view_instance}, then
a3b71f0f 845 - a view name in $c->stash->{current_view}, then
846 - a config setting 'default_view', or
847 - check if there is only one view, and return it if that's the case.
649fd1fa 848
2f381252 849If you want to search for views, pass in a regexp as the argument.
850
851 # find all views that start with Foo
852 my @foo_views = $c->view(qr{^Foo});
853
fc7ec1d9 854=cut
855
0ef52a96 856sub view {
197bd788 857 my ( $c, $name, @args ) = @_;
2f381252 858
df960201 859 my $appclass = ref($c) || $c;
2f381252 860 if( $name ) {
4995a5ce 861 unless ( $name->$_isa('Regexp') ) { # Direct component hash lookup to avoid costly regexps
13311c16 862 my $comps = $c->components;
863 my $check = $appclass."::View::".$name;
9c74923d 864 if( exists $comps->{$check} ) {
865 return $c->_filter_component( $comps->{$check}, @args );
866 }
867 else {
868 $c->log->warn( "Attempted to use view '$check', but does not exist" );
869 }
13311c16 870 }
2f381252 871 my @result = $c->_comp_search_prefixes( $name, qw/View V/ );
872 return map { $c->_filter_component( $_, @args ) } @result if ref $name;
873 return $c->_filter_component( $result[ 0 ], @args );
874 }
875
a3b71f0f 876 if (ref $c) {
62a6df80 877 return $c->stash->{current_view_instance}
a3b71f0f 878 if $c->stash->{current_view_instance};
879 return $c->view( $c->stash->{current_view} )
880 if $c->stash->{current_view};
a3b71f0f 881 }
df960201 882 return $c->view( $appclass->config->{default_view} )
883 if $appclass->config->{default_view};
2f381252 884
885 my( $comp, $rest ) = $c->_comp_search_prefixes( undef, qw/View V/);
886
887 if( $rest ) {
888 $c->log->warn( 'Calling $c->view() will return a random view unless you specify one of:' );
4600a5a1 889 $c->log->warn( '* $c->config(default_view => "the name of the default view to use")' );
2f381252 890 $c->log->warn( '* $c->stash->{current_view} # the name of the view to use for this request' );
891 $c->log->warn( '* $c->stash->{current_view_instance} # the instance of the view to use for this request' );
11c270bd 892 $c->log->warn( 'NB: in version 5.81, the "random" behavior will not work at all.' );
2f381252 893 }
894
895 return $c->_filter_component( $comp );
896}
897
898=head2 $c->controllers
899
900Returns the available names which can be passed to $c->controller
901
902=cut
903
904sub controllers {
905 my ( $c ) = @_;
906 return $c->_comp_names(qw/Controller C/);
0ef52a96 907}
fbcc39ad 908
b4b01a8a 909=head2 $c->models
910
911Returns the available names which can be passed to $c->model
912
913=cut
914
915sub models {
916 my ( $c ) = @_;
917 return $c->_comp_names(qw/Model M/);
918}
919
920
3b88a455 921=head2 $c->views
922
923Returns the available names which can be passed to $c->view
924
925=cut
926
927sub views {
928 my ( $c ) = @_;
929 return $c->_comp_names(qw/View V/);
930}
931
b4b01a8a 932=head2 $c->comp($name)
933
934=head2 $c->component($name)
935
cc95842f 936Gets a component object by name. This method is not recommended,
b4b01a8a 937unless you want to get a specific component by full
cc95842f 938class. C<< $c->controller >>, C<< $c->model >>, and C<< $c->view >>
b4b01a8a 939should be used instead.
940
2f381252 941If C<$name> is a regexp, a list of components matched against the full
942component name will be returned.
943
ab86b480 944If Catalyst can't find a component by name, it will fallback to regex
945matching by default. To disable this behaviour set
946disable_component_resolution_regex_fallback to a true value.
1d3a0700 947
220f4575 948 __PACKAGE__->config( disable_component_resolution_regex_fallback => 1 );
ab86b480 949
b4b01a8a 950=cut
951
952sub component {
2f381252 953 my ( $c, $name, @args ) = @_;
b4b01a8a 954
2f381252 955 if( $name ) {
956 my $comps = $c->components;
b4b01a8a 957
2f381252 958 if( !ref $name ) {
959 # is it the exact name?
960 return $c->_filter_component( $comps->{ $name }, @args )
961 if exists $comps->{ $name };
b4b01a8a 962
2f381252 963 # perhaps we just omitted "MyApp"?
964 my $composed = ( ref $c || $c ) . "::${name}";
965 return $c->_filter_component( $comps->{ $composed }, @args )
966 if exists $comps->{ $composed };
b4b01a8a 967
2f381252 968 # search all of the models, views and controllers
969 my( $comp ) = $c->_comp_search_prefixes( $name, qw/Model M Controller C View V/ );
970 return $c->_filter_component( $comp, @args ) if $comp;
971 }
972
f899107d 973 return
974 if $c->config->{disable_component_resolution_regex_fallback};
975
2f381252 976 # This is here so $c->comp( '::M::' ) works
977 my $query = ref $name ? $name : qr{$name}i;
b4b01a8a 978
2f381252 979 my @result = grep { m{$query} } keys %{ $c->components };
980 return map { $c->_filter_component( $_, @args ) } @result if ref $name;
b4b01a8a 981
2f381252 982 if( $result[ 0 ] ) {
108201b5 983 $c->log->warn( Carp::shortmess(qq(Found results for "${name}" using regexp fallback)) );
2f381252 984 $c->log->warn( 'Relying on the regexp fallback behavior for component resolution' );
985 $c->log->warn( 'is unreliable and unsafe. You have been warned' );
986 return $c->_filter_component( $result[ 0 ], @args );
987 }
988
989 # I would expect to return an empty list here, but that breaks back-compat
b4b01a8a 990 }
991
2f381252 992 # fallback
b4b01a8a 993 return sort keys %{ $c->components };
994}
995
b4b01a8a 996=head2 CLASS DATA AND HELPER CLASSES
fbcc39ad 997
b5ecfcf0 998=head2 $c->config
fbcc39ad 999
0ef52a96 1000Returns or takes a hashref containing the application's configuration.
1001
61b1d329 1002 __PACKAGE__->config( { db => 'dsn:SQLite:foo.db' } );
81557adf 1003
18a9655c 1004You can also use a C<YAML>, C<XML> or L<Config::General> config file
1005like C<myapp.conf> in your applications home directory. See
cc95842f 1006L<Catalyst::Plugin::ConfigLoader>.
a6ad13b6 1007
6df30f7e 1008=head3 Cascading configuration
a6ad13b6 1009
b3542016 1010The config method is present on all Catalyst components, and configuration
1011will be merged when an application is started. Configuration loaded with
1012L<Catalyst::Plugin::ConfigLoader> takes precedence over other configuration,
62a6df80 1013followed by configuration in your top level C<MyApp> class. These two
a51d14ff 1014configurations are merged, and then configuration data whose hash key matches a
b3542016 1015component name is merged with configuration for that component.
1016
1017The configuration for a component is then passed to the C<new> method when a
1018component is constructed.
1019
1020For example:
1021
1022 MyApp->config({ 'Model::Foo' => { bar => 'baz', overrides => 'me' } });
790ff9aa 1023 MyApp::Model::Foo->config({ quux => 'frob', overrides => 'this' });
62a6df80 1024
1025will mean that C<MyApp::Model::Foo> receives the following data when
b3542016 1026constructed:
1027
1028 MyApp::Model::Foo->new({
1029 bar => 'baz',
1030 quux => 'frob',
1031 overrides => 'me',
1032 });
b4b01a8a 1033
f8a54681 1034It's common practice to use a Moose attribute
1035on the receiving component to access the config value.
1036
1037 package MyApp::Model::Foo;
1038
1039 use Moose;
1040
1041 # this attr will receive 'baz' at construction time
9c74923d 1042 has 'bar' => (
f8a54681 1043 is => 'rw',
1044 isa => 'Str',
1045 );
1046
1047You can then get the value 'baz' by calling $c->model('Foo')->bar
9c74923d 1048(or $self->bar inside code in the model).
1049
1050B<NOTE:> you MUST NOT call C<< $self->config >> or C<< __PACKAGE__->config >>
1051as a way of reading config within your code, as this B<will not> give you the
1052correctly merged config back. You B<MUST> take the config values supplied to
1053the constructor and use those instead.
f8a54681 1054
3643e890 1055=cut
1056
4090e3bb 1057around config => sub {
1058 my $orig = shift;
3643e890 1059 my $c = shift;
1060
fcf89172 1061 croak('Setting config after setup has been run is not allowed.')
1062 if ( @_ and $c->setup_finished );
3643e890 1063
4090e3bb 1064 $c->$orig(@_);
1065};
3643e890 1066
b5ecfcf0 1067=head2 $c->log
0ef52a96 1068
86418559 1069Returns the logging object instance. Unless it is already set, Catalyst
1070sets this up with a L<Catalyst::Log> object. To use your own log class,
1071set the logger with the C<< __PACKAGE__->log >> method prior to calling
9e7673af 1072C<< __PACKAGE__->setup >>.
1073
1074 __PACKAGE__->log( MyLogger->new );
1075 __PACKAGE__->setup;
1076
1077And later:
0ef52a96 1078
ae1e6b59 1079 $c->log->info( 'Now logging with my own logger!' );
0ef52a96 1080
86418559 1081Your log class should implement the methods described in
1082L<Catalyst::Log>.
af3ff00e 1083
6adc45cf 1084=head2 has_encoding
1085
1086Returned True if there's a valid encoding
1087
1088=head2 clear_encoding
1089
1090Clears the encoding for the current context
1091
9c38cb50 1092=head2 encoding
1093
70005e98 1094Sets or gets the application encoding. Setting encoding takes either an
1095Encoding object or a string that we try to resolve via L<Encode::find_encoding>.
1096
1097You would expect to get the encoding object back if you attempt to set it. If
1098there is a failure you will get undef returned and an error message in the log.
9c38cb50 1099
1100=cut
1101
6adc45cf 1102sub has_encoding { shift->encoding ? 1:0 }
1103
1104sub clear_encoding {
1105 my $c = shift;
1106 if(blessed $c) {
1107 $c->encoding(undef);
1108 } else {
70005e98 1109 $c->log->error("You can't clear encoding on the application");
6adc45cf 1110 }
1111}
1112
9c38cb50 1113sub encoding {
1114 my $c = shift;
1115 my $encoding;
1116
1117 if ( scalar @_ ) {
70005e98 1118
1119 # Don't let one change this once we are too far into the response
1120 if(blessed $c && $c->res->finalized_headers) {
1121 Carp::croak("You may not change the encoding once the headers are finalized");
1122 return;
1123 }
1124
9c38cb50 1125 # Let it be set to undef
1126 if (my $wanted = shift) {
1127 $encoding = Encode::find_encoding($wanted)
1128 or Carp::croak( qq/Unknown encoding '$wanted'/ );
1129 binmode(STDERR, ':encoding(' . $encoding->name . ')');
1130 }
1131 else {
1132 binmode(STDERR);
1133 }
1134
1135 $encoding = ref $c
1136 ? $c->{encoding} = $encoding
1137 : $c->_encoding($encoding);
1138 } else {
1139 $encoding = ref $c && exists $c->{encoding}
1140 ? $c->{encoding}
1141 : $c->_encoding;
1142 }
1143
1144 return $encoding;
1145}
b4b01a8a 1146
1147=head2 $c->debug
1148
c74d3f0c 1149Returns 1 if debug mode is enabled, 0 otherwise.
b4b01a8a 1150
7e5c67f2 1151You can enable debug mode in several ways:
1152
1153=over
1154
62a6df80 1155=item By calling myapp_server.pl with the -d flag
1156
7e5c67f2 1157=item With the environment variables MYAPP_DEBUG, or CATALYST_DEBUG
1158
1159=item The -Debug option in your MyApp.pm
1160
8eae92ad 1161=item By declaring C<sub debug { 1 }> in your MyApp.pm.
7e5c67f2 1162
1163=back
c74d3f0c 1164
c8083f4e 1165The first three also set the log level to 'debug'.
1166
8eae92ad 1167Calling C<< $c->debug(1) >> has no effect.
e80e8542 1168
af3ff00e 1169=cut
1170
b4b01a8a 1171sub debug { 0 }
1172
1173=head2 $c->dispatcher
1174
2887a7f1 1175Returns the dispatcher instance. See L<Catalyst::Dispatcher>.
b4b01a8a 1176
1177=head2 $c->engine
1178
2887a7f1 1179Returns the engine instance. See L<Catalyst::Engine>.
b4b01a8a 1180
1181
f7b672ef 1182=head2 UTILITY METHODS
66e28e3f 1183
b5ecfcf0 1184=head2 $c->path_to(@path)
01033d73 1185
cc95842f 1186Merges C<@path> with C<< $c->config->{home} >> and returns a
4e392da6 1187L<Path::Class::Dir> object. Note you can usually use this object as
1188a filename, but sometimes you will have to explicitly stringify it
18a9655c 1189yourself by calling the C<< ->stringify >> method.
01033d73 1190
1191For example:
1192
1193 $c->path_to( 'db', 'sqlite.db' );
1194
1195=cut
1196
1197sub path_to {
1198 my ( $c, @path ) = @_;
a738ab68 1199 my $path = Path::Class::Dir->new( $c->config->{home}, @path );
01033d73 1200 if ( -d $path ) { return $path }
a738ab68 1201 else { return Path::Class::File->new( $c->config->{home}, @path ) }
01033d73 1202}
1203
0ef52a96 1204sub plugin {
1205 my ( $class, $name, $plugin, @args ) = @_;
6b2a933b 1206
4e68badc 1207 # See block comment in t/unit_core_plugin.t
3bdf9e57 1208 $class->log->warn(qq/Adding plugin using the ->plugin method is deprecated, and will be removed in a future release/);
4e68badc 1209
97b58e17 1210 $class->_register_plugin( $plugin, 1 );
0ef52a96 1211
1212 eval { $plugin->import };
1213 $class->mk_classdata($name);
1214 my $obj;
1215 eval { $obj = $plugin->new(@args) };
1216
1217 if ($@) {
1218 Catalyst::Exception->throw( message =>
1219 qq/Couldn't instantiate instant plugin "$plugin", "$@"/ );
1220 }
1221
1222 $class->$name($obj);
1223 $class->log->debug(qq/Initialized instant plugin "$plugin" as "$name"/)
1224 if $class->debug;
1225}
1226
b5ecfcf0 1227=head2 MyApp->setup
fbcc39ad 1228
e7f1cf73 1229Initializes the dispatcher and engine, loads any plugins, and loads the
ae1e6b59 1230model, view, and controller components. You may also specify an array
1231of plugins to load here, if you choose to not load them in the C<use
1232Catalyst> line.
fbcc39ad 1233
0ef52a96 1234 MyApp->setup;
1235 MyApp->setup( qw/-Debug/ );
fbcc39ad 1236
cf7ace24 1237B<Note:> You B<should not> wrap this method with method modifiers
1238or bad things will happen - wrap the C<setup_finalize> method instead.
1239
ac1cf8d4 1240B<Note:> You can create a custom setup stage that will execute when the
1241application is starting. Use this to customize setup.
1242
1243 MyApp->setup(-Custom=value);
1244
1245 sub setup_custom {
1246 my ($class, $value) = @_;
1247 }
1248
1249Can be handy if you want to hook into the setup phase.
1250
fbcc39ad 1251=cut
1252
1253sub setup {
0319a12c 1254 my ( $class, @arguments ) = @_;
c2f3cc1b 1255 croak('Running setup more than once')
1256 if ( $class->setup_finished );
5168a5fc 1257
fbcc39ad 1258 unless ( $class->isa('Catalyst') ) {
953b0e15 1259
fbcc39ad 1260 Catalyst::Exception->throw(
1261 message => qq/'$class' does not inherit from Catalyst/ );
1c99e125 1262 }
0319a12c 1263
fbcc39ad 1264 if ( $class->arguments ) {
1265 @arguments = ( @arguments, @{ $class->arguments } );
1266 }
1267
1268 # Process options
1269 my $flags = {};
1270
1271 foreach (@arguments) {
1272
1273 if (/^-Debug$/) {
1274 $flags->{log} =
1275 ( $flags->{log} ) ? 'debug,' . $flags->{log} : 'debug';
1276 }
1277 elsif (/^-(\w+)=?(.*)$/) {
1278 $flags->{ lc $1 } = $2;
1279 }
1280 else {
1281 push @{ $flags->{plugins} }, $_;
1282 }
1283 }
1284
99f187d6 1285 $class->setup_home( delete $flags->{home} );
1286
5bb2a5b3 1287 $class->setup_log( delete $flags->{log} );
fbcc39ad 1288 $class->setup_plugins( delete $flags->{plugins} );
17176f15 1289
b87d834e 1290 $class->setup_data_handlers();
fbcc39ad 1291 $class->setup_dispatcher( delete $flags->{dispatcher} );
acbecf08 1292 if (my $engine = delete $flags->{engine}) {
0aafa77a 1293 $class->log->warn("Specifying the engine in ->setup is no longer supported, see Catalyst::Upgrading");
acbecf08 1294 }
1295 $class->setup_engine();
dc5f035e 1296 $class->setup_stats( delete $flags->{stats} );
fbcc39ad 1297
1298 for my $flag ( sort keys %{$flags} ) {
1299
1300 if ( my $code = $class->can( 'setup_' . $flag ) ) {
1301 &$code( $class, delete $flags->{$flag} );
1302 }
1303 else {
1304 $class->log->warn(qq/Unknown flag "$flag"/);
1305 }
1306 }
1307
0eb4af72 1308 eval { require Catalyst::Devel; };
1309 if( !$@ && $ENV{CATALYST_SCRIPT_GEN} && ( $ENV{CATALYST_SCRIPT_GEN} < $Catalyst::Devel::CATALYST_SCRIPT_GEN ) ) {
1310 $class->log->warn(<<"EOF");
4ff0d824 1311You are running an old script!
1312
34a83d89 1313 Please update by running (this will overwrite existing files):
1314 catalyst.pl -force -scripts $class
1315
1316 or (this will not overwrite existing files):
1317 catalyst.pl -scripts $class
1cf0345b 1318
4ff0d824 1319EOF
0eb4af72 1320 }
62a6df80 1321
b677b4c2 1322 # Call plugins setup, this is stupid and evil.
1323 # Also screws C3 badly on 5.10, hack to avoid.
1324 {
1325 no warnings qw/redefine/;
1326 local *setup = sub { };
1327 $class->setup unless $Catalyst::__AM_RESTARTING;
1328 }
1329
9c38cb50 1330 # If you are expecting configuration info as part of your setup, it needs
1331 # to get called here and below, since we need the above line to support
1332 # ConfigLoader based configs.
1333
1334 $class->setup_encoding();
ac34e337 1335 $class->setup_middleware();
1336
02352a28 1337 # Initialize our data structure
1338 $class->components( {} );
1339
1340 $class->setup_components;
1341
fbcc39ad 1342 if ( $class->debug ) {
6601f2ad 1343 my @plugins = map { "$_ " . ( $_->VERSION || '' ) } $class->registered_plugins;
fbcc39ad 1344
1345 if (@plugins) {
39fc2ce1 1346 my $column_width = Catalyst::Utils::term_width() - 6;
1347 my $t = Text::SimpleTable->new($column_width);
8c113188 1348 $t->row($_) for @plugins;
1cf0345b 1349 $class->log->debug( "Loaded plugins:\n" . $t->draw . "\n" );
fbcc39ad 1350 }
1351
ba0b0de3 1352 my @middleware = map {
1353 ref $_ eq 'CODE' ?
1354 "Inline Coderef" :
ef5ad930 1355 (ref($_) .' '. ($_->can('VERSION') ? $_->VERSION || '' : '')
ba0b0de3 1356 || '') } $class->registered_middlewares;
10e39267 1357
1358 if (@middleware) {
1359 my $column_width = Catalyst::Utils::term_width() - 6;
1360 my $t = Text::SimpleTable->new($column_width);
1361 $t->row($_) for @middleware;
1362 $class->log->debug( "Loaded PSGI Middleware:\n" . $t->draw . "\n" );
1363 }
1364
ef5ad930 1365 my %dh = $class->registered_data_handlers;
1366 if (my @data_handlers = keys %dh) {
b87d834e 1367 my $column_width = Catalyst::Utils::term_width() - 6;
1368 my $t = Text::SimpleTable->new($column_width);
1369 $t->row($_) for @data_handlers;
1370 $class->log->debug( "Loaded Request Data Handlers:\n" . $t->draw . "\n" );
1371 }
1372
fbcc39ad 1373 my $dispatcher = $class->dispatcher;
1374 my $engine = $class->engine;
1375 my $home = $class->config->{home};
1376
01ce7075 1377 $class->log->debug(sprintf(q/Loaded dispatcher "%s"/, blessed($dispatcher)));
1378 $class->log->debug(sprintf(q/Loaded engine "%s"/, blessed($engine)));
fbcc39ad 1379
1380 $home
1381 ? ( -d $home )
1382 ? $class->log->debug(qq/Found home "$home"/)
1383 : $class->log->debug(qq/Home "$home" doesn't exist/)
1384 : $class->log->debug(q/Couldn't find home/);
fbcc39ad 1385
39fc2ce1 1386 my $column_width = Catalyst::Utils::term_width() - 8 - 9;
8860df07 1387
39fc2ce1 1388 my $t = Text::SimpleTable->new( [ $column_width, 'Class' ], [ 8, 'Type' ] );
684d10ed 1389 for my $comp ( sort keys %{ $class->components } ) {
1390 my $type = ref $class->components->{$comp} ? 'instance' : 'class';
1391 $t->row( $comp, $type );
1392 }
1cf0345b 1393 $class->log->debug( "Loaded components:\n" . $t->draw . "\n" )
8c113188 1394 if ( keys %{ $class->components } );
fbcc39ad 1395 }
1396
1397 # Add our self to components, since we are also a component
96d8d513 1398 if( $class->isa('Catalyst::Controller') ){
1399 $class->components->{$class} = $class;
1400 }
fbcc39ad 1401
1402 $class->setup_actions;
1403
1404 if ( $class->debug ) {
1405 my $name = $class->config->{name} || 'Application';
1406 $class->log->info("$name powered by Catalyst $Catalyst::VERSION");
1407 }
3643e890 1408
647a3de1 1409 if ($class->config->{case_sensitive}) {
1410 $class->log->warn($class . "->config->{case_sensitive} is set.");
1411 $class->log->warn("This setting is deprecated and planned to be removed in Catalyst 5.81.");
1412 }
1413
a5d07d29 1414 $class->setup_finalize;
1b526dcc 1415
1416 # Flush the log for good measure (in case something turned off 'autoflush' early)
647a3de1 1417 $class->log->_flush() if $class->log->can('_flush');
1b526dcc 1418
5077b8a3 1419 return $class || 1; # Just in case someone named their Application 0...
a5d07d29 1420}
1421
23c63a17 1422=head2 $app->setup_finalize
1423
128a7cee 1424A hook to attach modifiers to. This method does not do anything except set the
1425C<setup_finished> accessor.
23c63a17 1426
ae7da8f5 1427Applying method modifiers to the C<setup> method doesn't work, because of quirky things done for plugin setup.
23c63a17 1428
128a7cee 1429Example:
23c63a17 1430
128a7cee 1431 after setup_finalize => sub {
1432 my $app = shift;
23c63a17 1433
128a7cee 1434 ## do stuff here..
1435 };
23c63a17 1436
1437=cut
1438
a5d07d29 1439sub setup_finalize {
1440 my ($class) = @_;
3643e890 1441 $class->setup_finished(1);
fbcc39ad 1442}
1443
d71da6fe 1444=head2 $c->uri_for( $path?, @args?, \%query_values? )
fbcc39ad 1445
ee8963de 1446=head2 $c->uri_for( $action, \@captures?, @args?, \%query_values? )
9df7c5d9 1447
b063a165 1448=head2 $c->uri_for( $action, [@captures, @args], \%query_values? )
1449
ee8963de 1450Constructs an absolute L<URI> object based on the application root, the
1451provided path, and the additional arguments and query parameters provided.
186d5270 1452When used as a string, provides a textual URI. If you need more flexibility
92981fc3 1453than this (i.e. the option to provide relative URIs etc.) see
186d5270 1454L<Catalyst::Plugin::SmartURI>.
ee8963de 1455
d71da6fe 1456If no arguments are provided, the URI for the current action is returned.
1457To return the current action and also provide @args, use
1d3a0700 1458C<< $c->uri_for( $c->action, @args ) >>.
d71da6fe 1459
ee8963de 1460If the first argument is a string, it is taken as a public URI path relative
1461to C<< $c->namespace >> (if it doesn't begin with a forward slash) or
e7e4c469 1462relative to the application root (if it does). It is then merged with
ee8963de 1463C<< $c->request->base >>; any C<@args> are appended as additional path
1464components; and any C<%query_values> are appended as C<?foo=bar> parameters.
1465
1466If the first argument is a L<Catalyst::Action> it represents an action which
1467will have its path resolved using C<< $c->dispatcher->uri_for_action >>. The
1468optional C<\@captures> argument (an arrayref) allows passing the captured
1469variables that are needed to fill in the paths of Chained and Regex actions;
1470once the path is resolved, C<uri_for> continues as though a path was
1471provided, appending any arguments or parameters and creating an absolute
1472URI.
1473
e7e4c469 1474The captures for the current request can be found in
ee8963de 1475C<< $c->request->captures >>, and actions can be resolved using
1476C<< Catalyst::Controller->action_for($name) >>. If you have a private action
1477path, use C<< $c->uri_for_action >> instead.
1478
1479 # Equivalent to $c->req->uri
e7e4c469 1480 $c->uri_for($c->action, $c->req->captures,
ee8963de 1481 @{ $c->req->args }, $c->req->params);
62a6df80 1482
9df7c5d9 1483 # For the Foo action in the Bar controller
ee8963de 1484 $c->uri_for($c->controller('Bar')->action_for('Foo'));
9df7c5d9 1485
ee8963de 1486 # Path to a static resource
1487 $c->uri_for('/static/images/logo.png');
d5e3d528 1488
342d2169 1489In general the scheme of the generated URI object will follow the incoming request
1490however if your targeted action or action chain has the Scheme attribute it will
1491use that instead.
1492
d2b583c3 1493Also, if the targeted Action or Action chain declares Args/CaptureArgs that have
1494type constraints, we will require that your proposed URL verify on those declared
1495constraints.
1496
4cf1dd00 1497=cut
1498
fbcc39ad 1499sub uri_for {
00e6a2b7 1500 my ( $c, $path, @args ) = @_;
00e6a2b7 1501
0ee04045 1502 if ( $path->$_isa('Catalyst::Controller') ) {
7069eab5 1503 $path = $path->path_prefix;
1504 $path =~ s{/+\z}{};
1505 $path .= '/';
1506 }
1507
2689f8a4 1508 undef($path) if (defined $path && $path eq '');
1509
1510 my $params =
1511 ( scalar @args && ref $args[$#args] eq 'HASH' ? pop @args : {} );
1512
1513 carp "uri_for called with undef argument" if grep { ! defined $_ } @args;
5c779e98 1514
342d2169 1515 my $target_action = $path->$_isa('Catalyst::Action') ? $path : undef;
0ee04045 1516 if ( $path->$_isa('Catalyst::Action') ) { # action object
c042d18d 1517 s|/|%2F|g for @args;
2689f8a4 1518 my $captures = [ map { s|/|%2F|g; $_; }
c042d18d 1519 ( scalar @args && ref $args[0] eq 'ARRAY'
1520 ? @{ shift(@args) }
aaf72276 1521 : ()) ];
7b346bc3 1522
aa7e913e 1523 my $action = $path;
86a399db 1524 my $expanded_action = $c->dispatcher->expand_action( $action );
d2b583c3 1525 my $num_captures = $expanded_action->number_of_captures;
86a399db 1526
0cff119a 1527 # ->uri_for( $action, \@captures_and_args, \%query_values? )
c042d18d 1528 if( !@args && $action->number_of_args ) {
1529 unshift @args, splice @$captures, $num_captures;
0cff119a 1530 }
1531
86a399db 1532 if($num_captures) {
ec4d7259 1533 unless($expanded_action->match_captures_constraints($c, $captures)) {
1534 carp "captures [@{$captures}] do not match the type constraints in actionchain ending with '$expanded_action'";
86a399db 1535 return;
c1192f1e 1536 }
1537 }
1538
1539 $path = $c->dispatcher->uri_for_action($action, $captures);
aa7e913e 1540 if (not defined $path) {
1541 $c->log->debug(qq/Can't find uri_for action '$action' @$captures/)
1542 if $c->debug;
1543 return undef;
1544 }
81e75875 1545 $path = '/' if $path eq '';
c1192f1e 1546
1547 # At this point @encoded_args is the remaining Args (all captures removed).
86a399db 1548 if($expanded_action->has_args_constraints) {
c042d18d 1549 unless($expanded_action->match_args($c,\@args)) {
1550 carp "args [@args] do not match the type constraints in action '$expanded_action'";
86a399db 1551 return;
c1192f1e 1552 }
1553 }
ea0e58d9 1554 }
1555
c042d18d 1556 unshift(@args, $path);
51674a63 1557
1558 unless (defined $path && $path =~ s!^/!!) { # in-place strip
1559 my $namespace = $c->namespace;
1560 if (defined $path) { # cheesy hack to handle path '../foo'
c042d18d 1561 $namespace =~ s{(?:^|/)[^/]+$}{} while $args[0] =~ s{^\.\./}{};
6601f2ad 1562 }
c042d18d 1563 unshift(@args, $namespace || '');
51674a63 1564 }
62a6df80 1565
189e2a51 1566 # join args with '/', or a blank string
c042d18d 1567 my $args = join('/', grep { defined($_) } @args);
51674a63 1568 $args =~ s/\?/%3F/g; # STUPID STUPID SPECIAL CASE
e6968720 1569 $args =~ s!^/+!!;
f9451270 1570
1571 my ($base, $class) = ('/', 'URI::_generic');
1572 if(blessed($c)) {
1573 $base = $c->req->base;
342d2169 1574 if($target_action) {
1575 $target_action = $c->dispatcher->expand_action($target_action);
1576 if(my $s = $target_action->scheme) {
1577 $s = lc($s);
1578 $class = "URI::$s";
1579 $base->scheme($s);
1580 } else {
1581 $class = ref($base);
1582 }
1583 } else {
1584 $class = ref($base);
1585 }
1586
f9451270 1587 $base =~ s{(?<!/)$}{/};
1588 }
51674a63 1589
1590 my $query = '';
1591
1592 if (my @keys = keys %$params) {
1593 # somewhat lifted from URI::_query's query_form
1594 $query = '?'.join('&', map {
2f381252 1595 my $val = $params->{$_};
5c779e98 1596 #s/([;\/?:@&=+,\$\[\]%])/$URI::Escape::escapes{$1}/go; ## Commented out because seems to lead to double encoding - JNAP
51674a63 1597 s/ /+/g;
1598 my $key = $_;
51674a63 1599 $val = '' unless defined $val;
1600 (map {
1f851263 1601 my $param = "$_";
fdbf03db 1602 $param = encode_utf8($param);
51674a63 1603 # using the URI::Escape pattern here so utf8 chars survive
1f851263 1604 $param =~ s/([^A-Za-z0-9\-_.!~*'() ])/$URI::Escape::escapes{$1}/go;
1605 $param =~ s/ /+/g;
5c779e98 1606
fdbf03db 1607 $key = encode_utf8($key);
5c779e98 1608 # using the URI::Escape pattern here so utf8 chars survive
1609 $key =~ s/([^A-Za-z0-9\-_.!~*'() ])/$URI::Escape::escapes{$1}/go;
1610 $key =~ s/ /+/g;
1611
1f851263 1612 "${key}=$param"; } ( ref $val eq 'ARRAY' ? @$val : $val ));
51674a63 1613 } @keys);
1614 }
1615
d2b583c3 1616 $base = encode_utf8 $base;
1617 $base =~ s/([^$URI::uric])/$URI::Escape::escapes{$1}/go;
1618 $args = encode_utf8 $args;
1619 $args =~ s/([^$URI::uric])/$URI::Escape::escapes{$1}/go;
c1192f1e 1620
51674a63 1621 my $res = bless(\"${base}${args}${query}", $class);
d3e7a648 1622 $res;
fbcc39ad 1623}
1624
25d61080 1625=head2 $c->uri_for_action( $path, \@captures_and_args?, @args?, \%query_values? )
833b385e 1626
25d61080 1627=head2 $c->uri_for_action( $action, \@captures_and_args?, @args?, \%query_values? )
833b385e 1628
1629=over
1630
1631=item $path
1632
1633A private path to the Catalyst action you want to create a URI for.
1634
1635This is a shortcut for calling C<< $c->dispatcher->get_action_by_path($path)
1636>> and passing the resulting C<$action> and the remaining arguments to C<<
1637$c->uri_for >>.
1638
1639You can also pass in a Catalyst::Action object, in which case it is passed to
1640C<< $c->uri_for >>.
1641
c9ec25f8 1642Note that although the path looks like a URI that dispatches to the wanted action, it is not a URI, but an internal path to that action.
1643
1644For example, if the action looks like:
1645
1646 package MyApp::Controller::Users;
1647
1648 sub lst : Path('the-list') {}
1649
1650You can use:
1651
1652 $c->uri_for_action('/users/lst')
1653
1654and it will create the URI /users/the-list.
1655
25d61080 1656=item \@captures_and_args?
1657
1658Optional array reference of Captures (i.e. C<<CaptureArgs or $c->req->captures>)
1659and arguments to the request. Usually used with L<Catalyst::DispatchType::Chained>
1660to interpolate all the parameters in the URI.
1661
1662=item @args?
1663
942572d7 1664Optional list of extra arguments - can be supplied in the
1665C<< \@captures_and_args? >> array ref, or here - whichever is easier for your
1666code.
25d61080 1667
942572d7 1668Your action can have zero, a fixed or a variable number of args (e.g.
1669C<< Args(1) >> for a fixed number or C<< Args() >> for a variable number)..
25d61080 1670
1671=item \%query_values?
1672
1673Optional array reference of query parameters to append. E.g.
1674
1675 { foo => 'bar' }
1676
1677will generate
1678
1679 /rest/of/your/uri?foo=bar
1680
833b385e 1681=back
1682
1683=cut
1684
1685sub uri_for_action {
1686 my ( $c, $path, @args ) = @_;
62a6df80 1687 my $action = blessed($path)
1688 ? $path
833b385e 1689 : $c->dispatcher->get_action_by_path($path);
4ac0b9cb 1690 unless (defined $action) {
1691 croak "Can't find action for path '$path'";
1692 }
833b385e 1693 return $c->uri_for( $action, @args );
1694}
1695
b5ecfcf0 1696=head2 $c->welcome_message
ab2374d3 1697
1698Returns the Catalyst welcome HTML page.
1699
1700=cut
1701
1702sub welcome_message {
bf1f2c60 1703 my $c = shift;
1704 my $name = $c->config->{name};
1705 my $logo = $c->uri_for('/static/images/catalyst_logo.png');
1706 my $prefix = Catalyst::Utils::appprefix( ref $c );
80cdbbff 1707 $c->response->content_type('text/html; charset=utf-8');
ab2374d3 1708 return <<"EOF";
80cdbbff 1709<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1710 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1711<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
ab2374d3 1712 <head>
85d9fce6 1713 <meta http-equiv="Content-Language" content="en" />
1714 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
ab2374d3 1715 <title>$name on Catalyst $VERSION</title>
1716 <style type="text/css">
1717 body {
ab2374d3 1718 color: #000;
1719 background-color: #eee;
1720 }
1721 div#content {
1722 width: 640px;
80cdbbff 1723 margin-left: auto;
1724 margin-right: auto;
ab2374d3 1725 margin-top: 10px;
1726 margin-bottom: 10px;
1727 text-align: left;
1728 background-color: #ccc;
1729 border: 1px solid #aaa;
ab2374d3 1730 }
d84c4dab 1731 p, h1, h2 {
ab2374d3 1732 margin-left: 20px;
1733 margin-right: 20px;
16215972 1734 font-family: verdana, tahoma, sans-serif;
ab2374d3 1735 }
d84c4dab 1736 a {
1737 font-family: verdana, tahoma, sans-serif;
1738 }
d114e033 1739 :link, :visited {
1740 text-decoration: none;
1741 color: #b00;
1742 border-bottom: 1px dotted #bbb;
1743 }
1744 :link:hover, :visited:hover {
d114e033 1745 color: #555;
1746 }
ab2374d3 1747 div#topbar {
1748 margin: 0px;
1749 }
3e82a295 1750 pre {
3e82a295 1751 margin: 10px;
1752 padding: 8px;
1753 }
ab2374d3 1754 div#answers {
1755 padding: 8px;
1756 margin: 10px;
d114e033 1757 background-color: #fff;
ab2374d3 1758 border: 1px solid #aaa;
ab2374d3 1759 }
1760 h1 {
33108eaf 1761 font-size: 0.9em;
1762 font-weight: normal;
ab2374d3 1763 text-align: center;
1764 }
1765 h2 {
1766 font-size: 1.0em;
1767 }
1768 p {
1769 font-size: 0.9em;
1770 }
ae7c5252 1771 p img {
1772 float: right;
1773 margin-left: 10px;
1774 }
9619f23c 1775 span#appname {
1776 font-weight: bold;
33108eaf 1777 font-size: 1.6em;
ab2374d3 1778 }
1779 </style>
1780 </head>
1781 <body>
1782 <div id="content">
1783 <div id="topbar">
9619f23c 1784 <h1><span id="appname">$name</span> on <a href="http://catalyst.perl.org">Catalyst</a>
d84c4dab 1785 $VERSION</h1>
ab2374d3 1786 </div>
1787 <div id="answers">
ae7c5252 1788 <p>
80cdbbff 1789 <img src="$logo" alt="Catalyst Logo" />
ae7c5252 1790 </p>
596aaffe 1791 <p>Welcome to the world of Catalyst.
f92fd545 1792 This <a href="http://en.wikipedia.org/wiki/MVC">MVC</a>
1793 framework will make web development something you had
60dd6e1d 1794 never expected it to be: Fun, rewarding, and quick.</p>
ab2374d3 1795 <h2>What to do now?</h2>
4b8cb778 1796 <p>That really depends on what <b>you</b> want to do.
ab2374d3 1797 We do, however, provide you with a few starting points.</p>
1798 <p>If you want to jump right into web development with Catalyst
2f381252 1799 you might want to start with a tutorial.</p>
80267996 1800<pre>perldoc <a href="https://metacpan.org/module/Catalyst::Manual::Tutorial">Catalyst::Manual::Tutorial</a></code>
596aaffe 1801</pre>
1802<p>Afterwards you can go on to check out a more complete look at our features.</p>
1803<pre>
80267996 1804<code>perldoc <a href="https://metacpan.org/module/Catalyst::Manual::Intro">Catalyst::Manual::Intro</a>
b607f8a0 1805<!-- Something else should go here, but the Catalyst::Manual link seems unhelpful -->
1806</code></pre>
ab2374d3 1807 <h2>What to do next?</h2>
f5681c92 1808 <p>Next it's time to write an actual application. Use the
80267996 1809 helper scripts to generate <a href="https://metacpan.org/search?q=Catalyst%3A%3AController">controllers</a>,
1810 <a href="https://metacpan.org/search?q=Catalyst%3A%3AModel">models</a>, and
1811 <a href="https://metacpan.org/search?q=Catalyst%3A%3AView">views</a>;
bf1f2c60 1812 they can save you a lot of work.</p>
c5f31918 1813 <pre><code>script/${prefix}_create.pl --help</code></pre>
bf1f2c60 1814 <p>Also, be sure to check out the vast and growing
802bf2cb 1815 collection of <a href="http://search.cpan.org/search?query=Catalyst">plugins for Catalyst on CPAN</a>;
bf1f2c60 1816 you are likely to find what you need there.
f5681c92 1817 </p>
1818
82245cc4 1819 <h2>Need help?</h2>
f5681c92 1820 <p>Catalyst has a very active community. Here are the main places to
1821 get in touch with us.</p>
16215972 1822 <ul>
1823 <li>
2b9a7d76 1824 <a href="http://dev.catalyst.perl.org">Wiki</a>
16215972 1825 </li>
1826 <li>
6d4c3368 1827 <a href="http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst">Mailing-List</a>
16215972 1828 </li>
1829 <li>
4eaf7c88 1830 <a href="irc://irc.perl.org/catalyst">IRC channel #catalyst on irc.perl.org</a>
16215972 1831 </li>
1832 </ul>
ab2374d3 1833 <h2>In conclusion</h2>
62a6df80 1834 <p>The Catalyst team hopes you will enjoy using Catalyst as much
f5681c92 1835 as we enjoyed making it. Please contact us if you have ideas
1836 for improvement or other feedback.</p>
ab2374d3 1837 </div>
1838 </div>
1839 </body>
1840</html>
1841EOF
1842}
1843
aee7cdcc 1844=head2 run_options
1845
1846Contains a hash of options passed from the application script, including
c2c8d3cb 1847the original ARGV the script received, the processed values from that
aee7cdcc 1848ARGV and any extra arguments to the script which were not processed.
1849
1850This can be used to add custom options to your application's scripts
1851and setup your application differently depending on the values of these
1852options.
1853
fbcc39ad 1854=head1 INTERNAL METHODS
1855
ae1e6b59 1856These methods are not meant to be used by end users.
1857
b5ecfcf0 1858=head2 $c->components
fbcc39ad 1859
e7f1cf73 1860Returns a hash of components.
fbcc39ad 1861
b5ecfcf0 1862=head2 $c->context_class
1f9cb7c1 1863
e7f1cf73 1864Returns or sets the context class.
1f9cb7c1 1865
b5ecfcf0 1866=head2 $c->counter
fbcc39ad 1867
ae1e6b59 1868Returns a hashref containing coderefs and execution counts (needed for
1869deep recursion detection).
fbcc39ad 1870
b5ecfcf0 1871=head2 $c->depth
fbcc39ad 1872
e7f1cf73 1873Returns the number of actions on the current internal execution stack.
fbcc39ad 1874
b5ecfcf0 1875=head2 $c->dispatch
fbcc39ad 1876
e7f1cf73 1877Dispatches a request to actions.
fbcc39ad 1878
1879=cut
1880
1881sub dispatch { my $c = shift; $c->dispatcher->dispatch( $c, @_ ) }
1882
b5ecfcf0 1883=head2 $c->dispatcher_class
1f9cb7c1 1884
e7f1cf73 1885Returns or sets the dispatcher class.
1f9cb7c1 1886
b5ecfcf0 1887=head2 $c->dump_these
7f92deef 1888
ae1e6b59 1889Returns a list of 2-element array references (name, structure) pairs
1890that will be dumped on the error page in debug mode.
7f92deef 1891
1892=cut
1893
1894sub dump_these {
1895 my $c = shift;
62a6df80 1896 [ Request => $c->req ],
1897 [ Response => $c->res ],
052a2d89 1898 [ Stash => $c->stash ],
1899 [ Config => $c->config ];
7f92deef 1900}
1901
b5ecfcf0 1902=head2 $c->engine_class
1f9cb7c1 1903
e7f1cf73 1904Returns or sets the engine class.
1f9cb7c1 1905
b5ecfcf0 1906=head2 $c->execute( $class, $coderef )
fbcc39ad 1907
0ef52a96 1908Execute a coderef in given class and catch exceptions. Errors are available
1909via $c->error.
fbcc39ad 1910
1911=cut
1912
1913sub execute {
1914 my ( $c, $class, $code ) = @_;
858828dd 1915 $class = $c->component($class) || $class;
fbcc39ad 1916 $c->state(0);
a0eca838 1917
197bd788 1918 if ( $c->depth >= $RECURSION ) {
f3414019 1919 my $action = $code->reverse();
91d08727 1920 $action = "/$action" unless $action =~ /->/;
f3414019 1921 my $error = qq/Deep recursion detected calling "${action}"/;
1627551a 1922 $c->log->error($error);
1923 $c->error($error);
1924 $c->state(0);
1925 return $c->state;
1926 }
1927
dc5f035e 1928 my $stats_info = $c->_stats_start_execute( $code ) if $c->use_stats;
22247e54 1929
8767c5a3 1930 push( @{ $c->stack }, $code );
62a6df80 1931
6f3df815 1932 no warnings 'recursion';
524b0e1c 1933 # N.B. This used to be combined, but I have seen $c get clobbered if so, and
1934 # I have no idea how, ergo $ret (which appears to fix the issue)
1935 eval { my $ret = $code->execute( $class, $c, @{ $c->req->args } ) || 0; $c->state( $ret ) };
22247e54 1936
dc5f035e 1937 $c->_stats_finish_execute( $stats_info ) if $c->use_stats and $stats_info;
62a6df80 1938
a6724a82 1939 my $last = pop( @{ $c->stack } );
fbcc39ad 1940
1941 if ( my $error = $@ ) {
e25e23a7 1942 #rethow if this can be handled by middleware
80172e7d 1943 if ( $c->_handle_http_exception($error) ) {
30e84ba1 1944 foreach my $err (@{$c->error}) {
1945 $c->log->error($err);
1946 }
1947 $c->clear_errors;
1948 $c->log->_flush if $c->log->can('_flush');
1949
e25e23a7 1950 $error->can('rethrow') ? $error->rethrow : croak $error;
1951 }
79f5d571 1952 if ( blessed($error) and $error->isa('Catalyst::Exception::Detach') ) {
f87b7c21 1953 $error->rethrow if $c->depth > 1;
2f381252 1954 }
79f5d571 1955 elsif ( blessed($error) and $error->isa('Catalyst::Exception::Go') ) {
f87b7c21 1956 $error->rethrow if $c->depth > 0;
55424863 1957 }
fbcc39ad 1958 else {
1959 unless ( ref $error ) {
91d08727 1960 no warnings 'uninitialized';
fbcc39ad 1961 chomp $error;
f59def82 1962 my $class = $last->class;
1963 my $name = $last->name;
1964 $error = qq/Caught exception in $class->$name "$error"/;
fbcc39ad 1965 }
fbcc39ad 1966 $c->error($error);
fbcc39ad 1967 }
2688734f 1968 $c->state(0);
fbcc39ad 1969 }
1970 return $c->state;
1971}
1972
7a7d7af5 1973sub _stats_start_execute {
1974 my ( $c, $code ) = @_;
df960201 1975 my $appclass = ref($c) || $c;
a6724a82 1976 return if ( ( $code->name =~ /^_.*/ )
df960201 1977 && ( !$appclass->config->{show_internal_actions} ) );
7a7d7af5 1978
f3414019 1979 my $action_name = $code->reverse();
1980 $c->counter->{$action_name}++;
7a7d7af5 1981
f3414019 1982 my $action = $action_name;
a6724a82 1983 $action = "/$action" unless $action =~ /->/;
1984
7a7d7af5 1985 # determine if the call was the result of a forward
1986 # this is done by walking up the call stack and looking for a calling
1987 # sub of Catalyst::forward before the eval
1988 my $callsub = q{};
1989 for my $index ( 2 .. 11 ) {
1990 last
1991 if ( ( caller($index) )[0] eq 'Catalyst'
1992 && ( caller($index) )[3] eq '(eval)' );
1993
1994 if ( ( caller($index) )[3] =~ /forward$/ ) {
1995 $callsub = ( caller($index) )[3];
1996 $action = "-> $action";
1997 last;
1998 }
1999 }
2000
f3414019 2001 my $uid = $action_name . $c->counter->{$action_name};
74efc144 2002
a6724a82 2003 # is this a root-level call or a forwarded call?
2004 if ( $callsub =~ /forward$/ ) {
91740f34 2005 my $parent = $c->stack->[-1];
a6724a82 2006
2007 # forward, locate the caller
9c74923d 2008 if ( defined $parent && exists $c->counter->{"$parent"} ) {
69d8f33c 2009 $c->stats->profile(
62a6df80 2010 begin => $action,
69d8f33c 2011 parent => "$parent" . $c->counter->{"$parent"},
2012 uid => $uid,
2013 );
7a7d7af5 2014 }
2015 else {
2016
a6724a82 2017 # forward with no caller may come from a plugin
69d8f33c 2018 $c->stats->profile(
2019 begin => $action,
2020 uid => $uid,
2021 );
7a7d7af5 2022 }
2023 }
a6724a82 2024 else {
62a6df80 2025
a6724a82 2026 # root-level call
69d8f33c 2027 $c->stats->profile(
2028 begin => $action,
2029 uid => $uid,
2030 );
a6724a82 2031 }
dc5f035e 2032 return $action;
7a7d7af5 2033
7a7d7af5 2034}
2035
2036sub _stats_finish_execute {
2037 my ( $c, $info ) = @_;
69d8f33c 2038 $c->stats->profile( end => $info );
7a7d7af5 2039}
2040
b5ecfcf0 2041=head2 $c->finalize
fbcc39ad 2042
e7f1cf73 2043Finalizes the request.
fbcc39ad 2044
2045=cut
2046
2047sub finalize {
2048 my $c = shift;
2049
369c09bc 2050 for my $error ( @{ $c->error } ) {
2051 $c->log->error($error);
2052 }
2053
eb1f4b49 2054 # Support skipping finalize for psgix.io style 'jailbreak'. Used to support
2055 # stuff like cometd and websockets
c4df830e 2056
c2fef52f 2057 if($c->request->_has_io_fh) {
74bebe95 2058 $c->log_response;
2059 return;
2060 }
eb1f4b49 2061
5050d7a7 2062 # Allow engine to handle finalize flow (for POE)
e63bdf38 2063 my $engine = $c->engine;
2064 if ( my $code = $engine->can('finalize') ) {
2065 $engine->$code($c);
fbcc39ad 2066 }
5050d7a7 2067 else {
fbcc39ad 2068
5050d7a7 2069 $c->finalize_uploads;
fbcc39ad 2070
5050d7a7 2071 # Error
2072 if ( $#{ $c->error } >= 0 ) {
2073 $c->finalize_error;
2074 }
2075
9c38cb50 2076 $c->finalize_encoding;
89ba65d5 2077 $c->finalize_headers unless $c->response->finalized_headers;
5050d7a7 2078 $c->finalize_body;
2079 }
62a6df80 2080
2bf54936 2081 $c->log_response;
10f204e1 2082
62a6df80 2083 if ($c->use_stats) {
87b41398 2084 my $elapsed = $c->stats->elapsed;
12bf12c0 2085 my $av = $elapsed == 0 ? '??' : sprintf '%.3f', 1 / $elapsed;
908e3d9e 2086 $c->log->info(
62a6df80 2087 "Request took ${elapsed}s ($av/s)\n" . $c->stats->report . "\n" );
908e3d9e 2088 }
fbcc39ad 2089
2090 return $c->response->status;
2091}
2092
b5ecfcf0 2093=head2 $c->finalize_body
fbcc39ad 2094
e7f1cf73 2095Finalizes body.
fbcc39ad 2096
2097=cut
2098
2099sub finalize_body { my $c = shift; $c->engine->finalize_body( $c, @_ ) }
2100
b5ecfcf0 2101=head2 $c->finalize_cookies
fbcc39ad 2102
e7f1cf73 2103Finalizes cookies.
fbcc39ad 2104
2105=cut
2106
147821ea 2107sub finalize_cookies { my $c = shift; $c->engine->finalize_cookies( $c, @_ ) }
fbcc39ad 2108
b5ecfcf0 2109=head2 $c->finalize_error
fbcc39ad 2110
df93c9b5 2111Finalizes error. If there is only one error in L</error> and it is an object that
2112does C<as_psgi> or C<code> we rethrow the error and presume it caught by middleware
2113up the ladder. Otherwise we return the debugging error page (in debug mode) or we
2114return the default error page (production mode).
fbcc39ad 2115
2116=cut
2117
660f9bb0 2118sub finalize_error {
2119 my $c = shift;
2120 if($#{$c->error} > 0) {
2121 $c->engine->finalize_error( $c, @_ );
2122 } else {
2123 my ($error) = @{$c->error};
80172e7d 2124 if ( $c->_handle_http_exception($error) ) {
660f9bb0 2125 # In the case where the error 'knows what it wants', becauses its PSGI
2126 # aware, just rethow and let middleware catch it
2127 $error->can('rethrow') ? $error->rethrow : croak $error;
660f9bb0 2128 } else {
2129 $c->engine->finalize_error( $c, @_ )
2130 }
2131 }
2132}
fbcc39ad 2133
b5ecfcf0 2134=head2 $c->finalize_headers
fbcc39ad 2135
e7f1cf73 2136Finalizes headers.
fbcc39ad 2137
2138=cut
2139
2140sub finalize_headers {
2141 my $c = shift;
2142
e63bdf38 2143 my $response = $c->response; #accessor calls can add up?
2144
fbcc39ad 2145 # Check if we already finalized headers
6680c772 2146 return if $response->finalized_headers;
fbcc39ad 2147
2148 # Handle redirects
e63bdf38 2149 if ( my $location = $response->redirect ) {
fbcc39ad 2150 $c->log->debug(qq/Redirecting to "$location"/) if $c->debug;
e63bdf38 2151 $response->header( Location => $location );
fbcc39ad 2152 }
2153
9629478d 2154 # Remove incorrectly added body and content related meta data when returning
2155 # an information response, or a response the is required to not include a body
2156
fbcc39ad 2157 $c->finalize_cookies;
2158
6adc45cf 2159 # This currently is a NOOP but I don't want to remove it since I guess people
2160 # might have Response subclasses that use it for something... (JNAP)
89ba65d5 2161 $c->response->finalize_headers();
fbcc39ad 2162
2163 # Done
6680c772 2164 $response->finalized_headers(1);
fbcc39ad 2165}
2166
9c38cb50 2167=head2 $c->finalize_encoding
2168
4a64c27b 2169Make sure your body is encoded properly IF you set an encoding. By
566678d0 2170default the encoding is UTF-8 but you can disable it by explicitly setting the
dd096a3a 2171encoding configuration value to undef.
2172
6adc45cf 2173We can only encode when the body is a scalar. Methods for encoding via the
2174streaming interfaces (such as C<write> and C<write_fh> on L<Catalyst::Response>
2175are available).
2176
9c38cb50 2177See L</ENCODING>.
2178
2179=cut
2180
2181sub finalize_encoding {
2182 my $c = shift;
6adc45cf 2183 my $res = $c->res || return;
2184
2185 # Warn if the set charset is different from the one you put into encoding. We need
2186 # to do this early since encodable_response is false for this condition and we need
2187 # to match the debug output for backcompat (there's a test for this...) -JNAP
2188 if(
2189 $res->content_type_charset and $c->encoding and
2190 (uc($c->encoding->mime_name) ne uc($res->content_type_charset))
2191 ) {
2192 my $ct = lc($res->content_type_charset);
2193 $c->log->debug("Catalyst encoding config is set to encode in '" .
2194 $c->encoding->mime_name .
2195 "', content type is '$ct', not encoding ");
2196 }
9c38cb50 2197
6adc45cf 2198 if(
2199 ($res->encodable_response) and
2200 (defined($res->body)) and
2201 (ref(\$res->body) eq 'SCALAR')
2202 ) {
2203 $c->res->body( $c->encoding->encode( $c->res->body, $c->_encode_check ) );
9c38cb50 2204
6adc45cf 2205 # Set the charset if necessary. This might be a bit bonkers since encodable response
2206 # is false when the set charset is not the same as the encoding mimetype (maybe
2207 # confusing action at a distance here..
2208 # Don't try to set the charset if one already exists
2209 $c->res->content_type($c->res->content_type . "; charset=" . $c->encoding->mime_name)
2210 unless($c->res->content_type_charset);
9c38cb50 2211 }
9c38cb50 2212}
2213
b5ecfcf0 2214=head2 $c->finalize_output
fbcc39ad 2215
2216An alias for finalize_body.
2217
b5ecfcf0 2218=head2 $c->finalize_read
fbcc39ad 2219
e7f1cf73 2220Finalizes the input after reading is complete.
fbcc39ad 2221
2222=cut
2223
2224sub finalize_read { my $c = shift; $c->engine->finalize_read( $c, @_ ) }
2225
b5ecfcf0 2226=head2 $c->finalize_uploads
fbcc39ad 2227
ae1e6b59 2228Finalizes uploads. Cleans up any temporary files.
fbcc39ad 2229
2230=cut
2231
2232sub finalize_uploads { my $c = shift; $c->engine->finalize_uploads( $c, @_ ) }
2233
b5ecfcf0 2234=head2 $c->get_action( $action, $namespace )
fbcc39ad 2235
e7f1cf73 2236Gets an action in a given namespace.
fbcc39ad 2237
2238=cut
2239
684d10ed 2240sub get_action { my $c = shift; $c->dispatcher->get_action(@_) }
fbcc39ad 2241
b5ecfcf0 2242=head2 $c->get_actions( $action, $namespace )
a9dc674c 2243
ae1e6b59 2244Gets all actions of a given name in a namespace and all parent
2245namespaces.
a9dc674c 2246
2247=cut
2248
2249sub get_actions { my $c = shift; $c->dispatcher->get_actions( $c, @_ ) }
2250
e5ce5f04 2251=head2 $app->handle_request( @arguments )
fbcc39ad 2252
e7f1cf73 2253Called to handle each HTTP request.
fbcc39ad 2254
2255=cut
2256
2257sub handle_request {
2258 my ( $class, @arguments ) = @_;
2259
2260 # Always expect worst case!
2261 my $status = -1;
3640641e 2262 try {
dea1884f 2263 if ($class->debug) {
908e3d9e 2264 my $secs = time - $START || 1;
2265 my $av = sprintf '%.3f', $COUNT / $secs;
2266 my $time = localtime time;
2267 $class->log->info("*** Request $COUNT ($av/s) [$$] [$time] ***");
dea1884f 2268 }
908e3d9e 2269
2270 my $c = $class->prepare(@arguments);
2271 $c->dispatch;
62a6df80 2272 $status = $c->finalize;
660f9bb0 2273 } catch {
660f9bb0 2274 #rethow if this can be handled by middleware
80172e7d 2275 if ( $class->_handle_http_exception($_) ) {
6e94698d 2276 $_->can('rethrow') ? $_->rethrow : croak $_;
660f9bb0 2277 }
6e94698d 2278 chomp(my $error = $_);
2279 $class->log->error(qq/Caught exception in engine "$error"/);
3640641e 2280 };
fbcc39ad 2281
2282 $COUNT++;
62a6df80 2283
6680c772 2284 if(my $coderef = $class->log->can('_flush')){
2285 $class->log->$coderef();
2286 }
fbcc39ad 2287 return $status;
2288}
2289
d536010b 2290=head2 $class->prepare( @arguments )
fbcc39ad 2291
ae1e6b59 2292Creates a Catalyst context from an engine-specific request (Apache, CGI,
2293etc.).
fbcc39ad 2294
2295=cut
2296
398f13db 2297has _uploadtmp => (
2298 is => 'ro',
2299 predicate => '_has_uploadtmp',
2300);
2301
fbcc39ad 2302sub prepare {
2303 my ( $class, @arguments ) = @_;
2304
6680c772 2305 # XXX
2306 # After the app/ctxt split, this should become an attribute based on something passed
2307 # into the application.
3cec521a 2308 $class->context_class( ref $class || $class ) unless $class->context_class;
62a6df80 2309
398f13db 2310 my $uploadtmp = $class->config->{uploadtmp};
2311 my $c = $class->context_class->new({ $uploadtmp ? (_uploadtmp => $uploadtmp) : ()});
fbcc39ad 2312
258733f1 2313 $c->response->_context($c);
2314
395037a2 2315 $c->stats($class->stats_class->new)->enable($c->use_stats);
ec4d7259 2316
4f0b7cf1 2317 if ( $c->debug || $c->config->{enable_catalyst_header} ) {
62a6df80 2318 $c->res->headers->header( 'X-Catalyst' => $Catalyst::VERSION );
908e3d9e 2319 }
2320
3640641e 2321 try {
2322 # Allow engine to direct the prepare flow (for POE)
2323 if ( my $prepare = $c->engine->can('prepare') ) {
2324 $c->engine->$prepare( $c, @arguments );
2325 }
2326 else {
2327 $c->prepare_request(@arguments);
2328 $c->prepare_connection;
2329 $c->prepare_query_parameters;
41aaa5d6 2330 $c->prepare_headers; # Just hooks, no longer needed - they just
2331 $c->prepare_cookies; # cause the lazy attribute on req to build
3640641e 2332 $c->prepare_path;
2333
2334 # Prepare the body for reading, either by prepare_body
2335 # or the user, if they are using $c->read
2336 $c->prepare_read;
2337
2338 # Parse the body unless the user wants it on-demand
2339 unless ( ref($c)->config->{parse_on_demand} ) {
2340 $c->prepare_body;
2341 }
878b821c 2342 }
676bed72 2343 $c->prepare_action;
5050d7a7 2344 }
3640641e 2345 # VERY ugly and probably shouldn't rely on ->finalize actually working
2346 catch {
2347 # failed prepare is always due to an invalid request, right?
2348 $c->response->status(400);
2349 $c->response->content_type('text/plain');
2350 $c->response->body('Bad Request');
5e25c01f 2351 # Note we call finalize and then die here, which escapes
2352 # finalize being called in the enclosing block..
2353 # It in fact couldn't be called, as we don't return $c..
2354 # This is a mess - but I'm unsure you can fix this without
2355 # breaking compat for people doing crazy things (we should set
2356 # the 400 and just return the ctx here IMO, letting finalize get called
2357 # above...
3640641e 2358 $c->finalize;
2359 die $_;
2360 };
fbcc39ad 2361
10f204e1 2362 $c->log_request;
fbcc39ad 2363
2364 return $c;
2365}
2366
b5ecfcf0 2367=head2 $c->prepare_action
fbcc39ad 2368
b4b01a8a 2369Prepares action. See L<Catalyst::Dispatcher>.
fbcc39ad 2370
2371=cut
2372
9c38cb50 2373sub prepare_action {
2374 my $c = shift;
2375 my $ret = $c->dispatcher->prepare_action( $c, @_);
2376
2377 if($c->encoding) {
2378 foreach (@{$c->req->arguments}, @{$c->req->captures}) {
2379 $_ = $c->_handle_param_unicode_decoding($_);
2380 }
2381 }
2382
2383 return $ret;
2384}
2385
fbcc39ad 2386
b5ecfcf0 2387=head2 $c->prepare_body
fbcc39ad 2388
e7f1cf73 2389Prepares message body.
fbcc39ad 2390
2391=cut
2392
2393sub prepare_body {
2394 my $c = shift;
2395
0f56bbcf 2396 return if $c->request->_has_body;
fbcc39ad 2397
2398 # Initialize on-demand data
2399 $c->engine->prepare_body( $c, @_ );
2400 $c->prepare_parameters;
2401 $c->prepare_uploads;
fbcc39ad 2402}
2403
b5ecfcf0 2404=head2 $c->prepare_body_chunk( $chunk )
4bd82c41 2405
e7f1cf73 2406Prepares a chunk of data before sending it to L<HTTP::Body>.
4bd82c41 2407
b4b01a8a 2408See L<Catalyst::Engine>.
2409
4bd82c41 2410=cut
2411
4f5ebacd 2412sub prepare_body_chunk {
2413 my $c = shift;
4bd82c41 2414 $c->engine->prepare_body_chunk( $c, @_ );
2415}
2416
b5ecfcf0 2417=head2 $c->prepare_body_parameters
fbcc39ad 2418
e7f1cf73 2419Prepares body parameters.
fbcc39ad 2420
2421=cut
2422
2423sub prepare_body_parameters {
2424 my $c = shift;
b9d96e27 2425 $c->request->prepare_body_parameters( $c, @_ );
fbcc39ad 2426}
2427
b5ecfcf0 2428=head2 $c->prepare_connection
fbcc39ad 2429
e7f1cf73 2430Prepares connection.
fbcc39ad 2431
2432=cut
2433
2434sub prepare_connection {
2435 my $c = shift;
817ed8ab 2436 $c->request->prepare_connection($c);
fbcc39ad 2437}
2438
b5ecfcf0 2439=head2 $c->prepare_cookies
fbcc39ad 2440
41aaa5d6 2441Prepares cookies by ensuring that the attribute on the request
2442object has been built.
fbcc39ad 2443
2444=cut
2445
41aaa5d6 2446sub prepare_cookies { my $c = shift; $c->request->cookies }
fbcc39ad 2447
b5ecfcf0 2448=head2 $c->prepare_headers
fbcc39ad 2449
41aaa5d6 2450Prepares request headers by ensuring that the attribute on the request
2451object has been built.
fbcc39ad 2452
2453=cut
2454
41aaa5d6 2455sub prepare_headers { my $c = shift; $c->request->headers }
fbcc39ad 2456
b5ecfcf0 2457=head2 $c->prepare_parameters
fbcc39ad 2458
e7f1cf73 2459Prepares parameters.
fbcc39ad 2460
2461=cut
2462
2463sub prepare_parameters {
2464 my $c = shift;
2465 $c->prepare_body_parameters;
2466 $c->engine->prepare_parameters( $c, @_ );
2467}
2468
b5ecfcf0 2469=head2 $c->prepare_path
fbcc39ad 2470
e7f1cf73 2471Prepares path and base.
fbcc39ad 2472
2473=cut
2474
2475sub prepare_path { my $c = shift; $c->engine->prepare_path( $c, @_ ) }
2476
b5ecfcf0 2477=head2 $c->prepare_query_parameters
fbcc39ad 2478
e7f1cf73 2479Prepares query parameters.
fbcc39ad 2480
2481=cut
2482
2483sub prepare_query_parameters {
2484 my $c = shift;
2485
2486 $c->engine->prepare_query_parameters( $c, @_ );
10f204e1 2487}
fbcc39ad 2488
10f204e1 2489=head2 $c->log_request
2490
2491Writes information about the request to the debug logs. This includes:
2492
2493=over 4
2494
854e5dcd 2495=item * Request method, path, and remote IP address
10f204e1 2496
2497=item * Query keywords (see L<Catalyst::Request/query_keywords>)
2498
e7cbe1bf 2499=item * Request parameters
10f204e1 2500
2501=item * File uploads
2502
2503=back
fbcc39ad 2504
2505=cut
2506
10f204e1 2507sub log_request {
2508 my $c = shift;
fbcc39ad 2509
10f204e1 2510 return unless $c->debug;
fbcc39ad 2511
2bf54936 2512 my($dump) = grep {$_->[0] eq 'Request' } $c->dump_these;
2513 my $request = $dump->[1];
e7cbe1bf 2514
2515 my ( $method, $path, $address ) = ( $request->method, $request->path, $request->address );
10f204e1 2516 $method ||= '';
2517 $path = '/' unless length $path;
2518 $address ||= '';
0ca510f0 2519
2520 $path =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;
2521 $path = decode_utf8($path);
2522
10f204e1 2523 $c->log->debug(qq/"$method" request for "$path" from "$address"/);
2524
3a4abdb3 2525 $c->log_request_headers($request->headers);
e7cbe1bf 2526
2527 if ( my $keywords = $request->query_keywords ) {
10f204e1 2528 $c->log->debug("Query keywords are: $keywords");
fbcc39ad 2529 }
10f204e1 2530
9c74923d 2531 $c->log_request_parameters( query => $request->query_parameters, $request->_has_body ? (body => $request->body_parameters) : () );
10f204e1 2532
e7cbe1bf 2533 $c->log_request_uploads($request);
fbcc39ad 2534}
2535
10f204e1 2536=head2 $c->log_response
fbcc39ad 2537
75b65816 2538Writes information about the response to the debug logs by calling
2539C<< $c->log_response_status_line >> and C<< $c->log_response_headers >>.
fbcc39ad 2540
2541=cut
2542
75b65816 2543sub log_response {
2544 my $c = shift;
fbcc39ad 2545
75b65816 2546 return unless $c->debug;
fbcc39ad 2547
75b65816 2548 my($dump) = grep {$_->[0] eq 'Response' } $c->dump_these;
2549 my $response = $dump->[1];
2550
2551 $c->log_response_status_line($response);
2552 $c->log_response_headers($response->headers);
2553}
2554
2555=head2 $c->log_response_status_line($response)
2556
2557Writes one line of information about the response to the debug logs. This includes:
10f204e1 2558
2559=over 4
2560
2561=item * Response status code
2562
3a4abdb3 2563=item * Content-Type header (if present)
2564
2565=item * Content-Length header (if present)
10f204e1 2566
2567=back
fbcc39ad 2568
2569=cut
2570
75b65816 2571sub log_response_status_line {
2572 my ($c, $response) = @_;
fbcc39ad 2573
697bab77 2574 $c->log->debug(
2575 sprintf(
2576 'Response Code: %s; Content-Type: %s; Content-Length: %s',
2577 $response->status || 'unknown',
2578 $response->headers->header('Content-Type') || 'unknown',
2579 $response->headers->header('Content-Length') || 'unknown'
2580 )
2581 );
10f204e1 2582}
fbcc39ad 2583
75b65816 2584=head2 $c->log_response_headers($headers);
2585
8ad6fd58 2586Hook method which can be wrapped by plugins to log the response headers.
75b65816 2587No-op in the default implementation.
fbcc39ad 2588
2589=cut
2590
75b65816 2591sub log_response_headers {}
fbcc39ad 2592
10f204e1 2593=head2 $c->log_request_parameters( query => {}, body => {} )
2594
2595Logs request parameters to debug logs
2596
10f204e1 2597=cut
2598
2599sub log_request_parameters {
2600 my $c = shift;
2601 my %all_params = @_;
2602
2bf54936 2603 return unless $c->debug;
e7cbe1bf 2604
10f204e1 2605 my $column_width = Catalyst::Utils::term_width() - 44;
2606 foreach my $type (qw(query body)) {
2bf54936 2607 my $params = $all_params{$type};
2608 next if ! keys %$params;
10f204e1 2609 my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ $column_width, 'Value' ] );
e7cbe1bf 2610 for my $key ( sort keys %$params ) {
2611 my $param = $params->{$key};
10f204e1 2612 my $value = defined($param) ? $param : '';
2613 $t->row( $key, ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
2614 }
2615 $c->log->debug( ucfirst($type) . " Parameters are:\n" . $t->draw );
2616 }
2617}
2618
2619=head2 $c->log_request_uploads
2620
2621Logs file uploads included in the request to the debug logs.
854e5dcd 2622The parameter name, filename, file type, and file size are all included in
10f204e1 2623the debug logs.
2624
2625=cut
fbcc39ad 2626
10f204e1 2627sub log_request_uploads {
2628 my $c = shift;
2bf54936 2629 my $request = shift;
e7cbe1bf 2630 return unless $c->debug;
2631 my $uploads = $request->uploads;
10f204e1 2632 if ( keys %$uploads ) {
8c113188 2633 my $t = Text::SimpleTable->new(
34d28dfd 2634 [ 12, 'Parameter' ],
2635 [ 26, 'Filename' ],
8c113188 2636 [ 18, 'Type' ],
2637 [ 9, 'Size' ]
2638 );
10f204e1 2639 for my $key ( sort keys %$uploads ) {
2640 my $upload = $uploads->{$key};
fbcc39ad 2641 for my $u ( ref $upload eq 'ARRAY' ? @{$upload} : ($upload) ) {
8c113188 2642 $t->row( $key, $u->filename, $u->type, $u->size );
fbcc39ad 2643 }
2644 }
2645 $c->log->debug( "File Uploads are:\n" . $t->draw );
2646 }
2647}
2648
3a4abdb3 2649=head2 $c->log_request_headers($headers);
2650
2651Hook method which can be wrapped by plugins to log the request headers.
2652No-op in the default implementation.
2653
2654=cut
2655
2656sub log_request_headers {}
2657
10f204e1 2658=head2 $c->log_headers($type => $headers)
2659
e7cbe1bf 2660Logs L<HTTP::Headers> (either request or response) to the debug logs.
10f204e1 2661
2662=cut
2663
2664sub log_headers {
2665 my $c = shift;
2666 my $type = shift;
2667 my $headers = shift; # an HTTP::Headers instance
2668
e7cbe1bf 2669 return unless $c->debug;
10f204e1 2670
f0e9921a 2671 my $column_width = Catalyst::Utils::term_width() - 28;
2672 my $t = Text::SimpleTable->new( [ 15, 'Header Name' ], [ $column_width, 'Value' ] );
e7cbe1bf 2673 $headers->scan(
10f204e1 2674 sub {
2675 my ( $name, $value ) = @_;
2676 $t->row( $name, $value );
2677 }
2678 );
2679 $c->log->debug( ucfirst($type) . " Headers:\n" . $t->draw );
2680}
2681
10f204e1 2682
2683=head2 $c->prepare_read
2684
2685Prepares the input for reading.
2686
2687=cut
2688
2689sub prepare_read { my $c = shift; $c->engine->prepare_read( $c, @_ ) }
2690
2691=head2 $c->prepare_request
2692
2693Prepares the engine request.
2694
2695=cut
2696
2697sub prepare_request { my $c = shift; $c->engine->prepare_request( $c, @_ ) }
2698
2699=head2 $c->prepare_uploads
2700
2701Prepares uploads.
2702
2703=cut
2704
2705sub prepare_uploads {
2706 my $c = shift;
10f204e1 2707 $c->engine->prepare_uploads( $c, @_ );
2708}
2709
b5ecfcf0 2710=head2 $c->prepare_write
fbcc39ad 2711
e7f1cf73 2712Prepares the output for writing.
fbcc39ad 2713
2714=cut
2715
2716sub prepare_write { my $c = shift; $c->engine->prepare_write( $c, @_ ) }
2717
b5ecfcf0 2718=head2 $c->request_class
1f9cb7c1 2719
3f87d500 2720Returns or sets the request class. Defaults to L<Catalyst::Request>.
1f9cb7c1 2721
ec4d7259 2722=head2 $app->request_class_traits
2723
2724An arrayref of L<Moose::Role>s which are applied to the request class.
2725
2726=head2 $app->composed_request_class
2727
2728This is the request class which has been composed with any request_class_traits.
2729
b5ecfcf0 2730=head2 $c->response_class
1f9cb7c1 2731
3f87d500 2732Returns or sets the response class. Defaults to L<Catalyst::Response>.
1f9cb7c1 2733
ec4d7259 2734=head2 $app->response_class_traits
2735
2736An arrayref of L<Moose::Role>s which are applied to the response class.
2737
2738=head2 $app->composed_response_class
2739
2740This is the request class which has been composed with any response_class_traits.
2741
b5ecfcf0 2742=head2 $c->read( [$maxlength] )
fbcc39ad 2743
ae1e6b59 2744Reads a chunk of data from the request body. This method is designed to
2745be used in a while loop, reading C<$maxlength> bytes on every call.
2746C<$maxlength> defaults to the size of the request if not specified.
fbcc39ad 2747
4600a5a1 2748You have to set C<< MyApp->config(parse_on_demand => 1) >> to use this
ae1e6b59 2749directly.
fbcc39ad 2750
878b821c 2751Warning: If you use read(), Catalyst will not process the body,
2752so you will not be able to access POST parameters or file uploads via
2753$c->request. You must handle all body parsing yourself.
2754
fbcc39ad 2755=cut
2756
f083854e 2757sub read { my $c = shift; return $c->request->read( @_ ) }
fbcc39ad 2758
b5ecfcf0 2759=head2 $c->run
fbcc39ad 2760
2761Starts the engine.