File Coverage

blib/lib/Catalyst.pm
Criterion Covered Total %
statement 503 688 73.1
branch 169 294 57.5
condition 55 119 46.2
subroutine 93 111 83.8
pod 62 62 100.0
total 882 1274 69.2


line stmt bran cond sub pod time code
1             package Catalyst;
2              
3 55     55   1423 use strict;
  55         535  
  55         946  
4 55     55   2326 use base 'Catalyst::Component';
  55         806  
  55         2900  
5 55     55   45418 use bytes;
  55         787  
  55         923  
6 55     55   1008 use Catalyst::Exception;
  55         566  
  55         1175  
7 55     55   1515 use Catalyst::Log;
  55         566  
  55         4305  
8 55     55   1712 use Catalyst::Request;
  55         675  
  55         1275  
9 55     55   4288 use Catalyst::Request::Upload;
  55         623  
  55         1553  
10 55     55   3293 use Catalyst::Response;
  55         2759  
  55         1190  
11 55     55   1074 use Catalyst::Utils;
  55         564  
  55         891  
12 55     55   1913 use Catalyst::Controller;
  55         618  
  55         2085  
13 55     55   2621 use Devel::InnerPackage ();
  55         613  
  55         587  
14 55     55   1017 use File::stat;
  55         607  
  55         880  
15 55     55   3061 use Module::Pluggable::Object ();
  55         1422  
  55         857  
16 55     55   1911 use NEXT;
  55         674  
  55         1148  
17 55     55   2304 use Text::SimpleTable ();
  55         922  
  55         601  
18 55     55   1657 use Path::Class::Dir ();
  55         3725  
  55         606  
19 55     55   5323 use Path::Class::File ();
  55         524  
  55         542  
20 55     55   2357 use Time::HiRes qw/gettimeofday tv_interval/;
  55         691  
  55         899  
21 55     55   1143 use URI ();
  55         895  
  55         742  
22 55     55   999 use Scalar::Util qw/weaken blessed/;
  55         511  
  55         1616  
23 55     55   3207 use Tree::Simple qw/use_weak_refs/;
  55         1506  
  55         1157  
24 55     55   2441 use Tree::Simple::Visitor::FindByUID;
  55         22821  
  55         2226  
25 55     55   1891 use attributes;
  55         527  
  55         1247  
26 55     55   948 use utf8;
  55         583  
  55         872  
27 55     55   2654 use Carp qw/croak/;
  55         539  
  55         1154  
28              
29 55     55   805 BEGIN { require 5.008001; }
30              
31             __PACKAGE__->mk_accessors(
32                 qw/counter request response state action stack namespace stats/
33             );
34              
35             attributes->import( __PACKAGE__, \&namespace, 'lvalue' );
36              
37 8484 50   8484 1 104464 sub depth { scalar @{ shift->stack || [] }; }
  8484         141409  
38              
39             # Laziness++
40             *comp = \&component;
41             *req  = \&request;
42             *res  = \&response;
43              
44             # For backwards compatibility
45             *finalize_output = \&finalize_body;
46              
47             # For statistics
48             our $COUNT = 1;
49             our $START = time;
50             our $RECURSION = 1000;
51             our $DETACH = "catalyst_detach\n";
52              
53             __PACKAGE__->mk_classdata($_)
54               for qw/components arguments dispatcher engine log dispatcher_class
55             engine_class context_class request_class response_class setup_finished/;
56              
57             __PACKAGE__->dispatcher_class('Catalyst::Dispatcher');
58             __PACKAGE__->engine_class('Catalyst::Engine::CGI');
59             __PACKAGE__->request_class('Catalyst::Request');
60             __PACKAGE__->response_class('Catalyst::Response');
61              
62             # Remember to update this in Catalyst::Runtime as well!
63              
64             our $VERSION = '5.7007';
65              
66             sub import {
67 105     105   1438     my ( $class, @arguments ) = @_;
68              
69             # We have to limit $class to Catalyst to avoid pushing Catalyst upon every
70             # callers @ISA.
71 105 100       1519     return unless $class eq 'Catalyst';
72              
73 58         704     my $caller = caller(0);
74              
75 58 50       8845     unless ( $caller->isa('Catalyst') ) {
76 55     55   2746         no strict 'refs';
  55         558  
  55         926  
77 58         863         push @{"$caller\::ISA"}, $class, 'Catalyst::Controller';
  58         1353  
78                 }
79              
80 58         1433     $caller->arguments( [@arguments] );
81 58         1037     $caller->setup_home;
82             }
83              
84             =head1 NAME
85            
86             Catalyst - The Elegant MVC Web Application Framework
87            
88             =head1 SYNOPSIS
89            
90             See the L<Catalyst::Manual> distribution for comprehensive
91             documentation and tutorials.
92            
93             # Install Catalyst::Devel for helpers and other development tools
94             # use the helper to create a new application
95             catalyst.pl MyApp
96            
97             # add models, views, controllers
98             script/myapp_create.pl model MyDatabase DBIC::Schema create=dynamic dbi:SQLite:/path/to/db
99             script/myapp_create.pl view MyTemplate TT
100             script/myapp_create.pl controller Search
101            
102             # built in testserver -- use -r to restart automatically on changes
103             # --help to see all available options
104             script/myapp_server.pl
105            
106             # command line testing interface
107             script/myapp_test.pl /yada
108            
109             ### in lib/MyApp.pm
110             use Catalyst qw/-Debug/; # include plugins here as well
111            
112             ### In lib/MyApp/Controller/Root.pm (autocreated)
113             sub foo : Global { # called for /foo, /foo/1, /foo/1/2, etc.
114             my ( $self, $c, @args ) = @_; # args are qw/1 2/ for /foo/1/2
115             $c->stash->{template} = 'foo.tt'; # set the template
116             # lookup something from db -- stash vars are passed to TT
117             $c->stash->{data} =
118             $c->model('Database::Foo')->search( { country => $args[0] } );
119             if ( $c->req->params->{bar} ) { # access GET or POST parameters
120             $c->forward( 'bar' ); # process another action
121             # do something else after forward returns
122             }
123             }
124            
125             # The foo.tt TT template can use the stash data from the database
126             [% WHILE (item = data.next) %]
127             [% item.foo %]
128             [% END %]
129            
130             # called for /bar/of/soap, /bar/of/soap/10, etc.
131             sub bar : Path('/bar/of/soap') { ... }
132            
133             # called for all actions, from the top-most controller downwards
134             sub auto : Private {
135             my ( $self, $c ) = @_;
136             if ( !$c->user_exists ) { # Catalyst::Plugin::Authentication
137             $c->res->redirect( '/login' ); # require login
138             return 0; # abort request and go immediately to end()
139             }
140             return 1; # success; carry on to next action
141             }
142            
143             # called after all actions are finished
144             sub end : Private {
145             my ( $self, $c ) = @_;
146             if ( scalar @{ $c->error } ) { ... } # handle errors
147             return if $c->res->body; # already have a response
148             $c->forward( 'MyApp::View::TT' ); # render template
149             }
150            
151             ### in MyApp/Controller/Foo.pm
152             # called for /foo/bar
153             sub bar : Local { ... }
154            
155             # called for /blargle
156             sub blargle : Global { ... }
157            
158             # an index action matches /foo, but not /foo/1, etc.
159             sub index : Private { ... }
160            
161             ### in MyApp/Controller/Foo/Bar.pm
162             # called for /foo/bar/baz
163             sub baz : Local { ... }
164            
165             # first Root auto is called, then Foo auto, then this
166             sub auto : Private { ... }
167            
168             # powerful regular expression paths are also possible
169             sub details : Regex('^product/(\w+)/details$') {
170             my ( $self, $c ) = @_;
171             # extract the (\w+) from the URI
172             my $product = $c->req->captures->[0];
173             }
174            
175             See L<Catalyst::Manual::Intro> for additional information.
176            
177             =head1 DESCRIPTION
178            
179             Catalyst is a modern framework for making web applications without the
180             pain usually associated with this process. This document is a reference
181             to the main Catalyst application. If you are a new user, we suggest you
182             start with L<Catalyst::Manual::Tutorial> or L<Catalyst::Manual::Intro>.
183            
184             See L<Catalyst::Manual> for more documentation.
185            
186             Catalyst plugins can be loaded by naming them as arguments to the "use
187             Catalyst" statement. Omit the C<Catalyst::Plugin::> prefix from the
188             plugin name, i.e., C<Catalyst::Plugin::My::Module> becomes
189             C<My::Module>.
190            
191             use Catalyst qw/My::Module/;
192            
193             If your plugin starts with a name other than C<Catalyst::Plugin::>, you can
194             fully qualify the name by using a unary plus:
195            
196             use Catalyst qw/
197             My::Module
198             +Fully::Qualified::Plugin::Name
199             /;
200            
201             Special flags like C<-Debug> and C<-Engine> can also be specified as
202             arguments when Catalyst is loaded:
203            
204             use Catalyst qw/-Debug My::Module/;
205            
206             The position of plugins and flags in the chain is important, because
207             they are loaded in the order in which they appear.
208            
209             The following flags are supported:
210            
211             =head2 -Debug
212            
213             Enables debug output. You can also force this setting from the system
214             environment with CATALYST_DEBUG or <MYAPP>_DEBUG. The environment
215             settings override the application, with <MYAPP>_DEBUG having the highest
216             priority.
217            
218             =head2 -Engine
219            
220             Forces Catalyst to use a specific engine. Omit the
221             C<Catalyst::Engine::> prefix of the engine name, i.e.:
222            
223             use Catalyst qw/-Engine=CGI/;
224            
225             =head2 -Home
226            
227             Forces Catalyst to use a specific home directory, e.g.:
228            
229             use Catalyst qw[-Home=/usr/mst];
230            
231             This can also be done in the shell environment by setting either the
232             C<CATALYST_HOME> environment variable or C<MYAPP_HOME>; where C<MYAPP>
233             is replaced with the uppercased name of your application, any "::" in
234             the name will be replaced with underscores, e.g. MyApp::Web should use
235             MYAPP_WEB_HOME. If both variables are set, the MYAPP_HOME one will be used.
236            
237             =head2 -Log
238            
239             Specifies log level.
240            
241             =head1 METHODS
242            
243             =head2 INFORMATION ABOUT THE CURRENT REQUEST
244            
245             =head2 $c->action
246            
247             Returns a L<Catalyst::Action> object for the current action, which
248             stringifies to the action name. See L<Catalyst::Action>.
249            
250             =head2 $c->namespace
251            
252             Returns the namespace of the current action, i.e., the URI prefix
253             corresponding to the controller of the current action. For example:
254            
255             # in Controller::Foo::Bar
256             $c->namespace; # returns 'foo/bar';
257            
258             =head2 $c->request
259            
260             =head2 $c->req
261            
262             Returns the current L<Catalyst::Request> object, giving access to
263             information about the current client request (including parameters,
264             cookies, HTTP headers, etc.). See L<Catalyst::Request>.
265            
266             =head2 REQUEST FLOW HANDLING
267            
268             =head2 $c->forward( $action [, \@arguments ] )
269            
270             =head2 $c->forward( $class, $method, [, \@arguments ] )
271            
272             Forwards processing to another action, by its private name. If you give a
273             class name but no method, C<process()> is called. You may also optionally
274             pass arguments in an arrayref. The action will receive the arguments in
275             C<@_> and C<< $c->req->args >>. Upon returning from the function,
276             C<< $c->req->args >> will be restored to the previous values.
277            
278             Any data C<return>ed from the action forwarded to, will be returned by the
279             call to forward.
280            
281             my $foodata = $c->forward('/foo');
282             $c->forward('index');
283             $c->forward(qw/MyApp::Model::DBIC::Foo do_stuff/);
284             $c->forward('MyApp::View::TT');
285            
286             Note that forward implies an C<<eval { }>> around the call (actually
287             C<execute> does), thus de-fatalizing all 'dies' within the called
288             action. If you want C<die> to propagate you need to do something like:
289            
290             $c->forward('foo');
291             die $c->error if $c->error;
292            
293             Or make sure to always return true values from your actions and write
294             your code like this:
295            
296             $c->forward('foo') || return;
297            
298             =cut
299              
300 6199     6199 1 114220 sub forward { my $c = shift; $c->dispatcher->forward( $c, @_ ) }
  6199         99125  
301              
302             =head2 $c->detach( $action [, \@arguments ] )
303            
304             =head2 $c->detach( $class, $method, [, \@arguments ] )
305            
306             =head2 $c->detach()
307            
308             The same as C<forward>, but doesn't return to the previous action when
309             processing is finished.
310            
311             When called with no arguments it escapes the processing chain entirely.
312            
313             =cut
314              
315 12     12 1 477 sub detach { my $c = shift; $c->dispatcher->detach( $c, @_ ) }
  12         160  
316              
317             =head2 $c->response
318            
319             =head2 $c->res
320            
321             Returns the current L<Catalyst::Response> object, see there for details.
322            
323             =head2 $c->stash
324            
325             Returns a hashref to the stash, which may be used to store data and pass
326             it between components during a request. You can also set hash keys by
327             passing arguments. The stash is automatically sent to the view. The
328             stash is cleared at the end of a request; it cannot be used for
329             persistent storage (for this you must use a session; see
330             L<Catalyst::Plugin::Session> for a complete system integrated with
331             Catalyst).
332            
333             $c->stash->{foo} = $bar;
334             $c->stash( { moose => 'majestic', qux => 0 } );
335             $c->stash( bar => 1, gorch => 2 ); # equivalent to passing a hashref
336            
337             # stash is automatically passed to the view for use in a template
338             $c->forward( 'MyApp::View::TT' );
339            
340             =cut
341              
342             sub stash {
343 280     280 1 9857     my $c = shift;
344 280 50       2875     if (@_) {
345 0 0       0         my $stash = @_ > 1 ? {@_} : $_[0];
346 0 0       0 croak('stash takes a hash or hashref') unless ref $stash;
347 0         0         foreach my $key ( keys %$stash ) {
348 0         0             $c->{stash}->{$key} = $stash->{$key};
349                     }
350                 }
351 280         5213     return $c->{stash};
352             }
353              
354             =head2 $c->error
355            
356             =head2 $c->error($error, ...)
357            
358             =head2 $c->error($arrayref)
359            
360             Returns an arrayref containing error messages. If Catalyst encounters an
361             error while processing a request, it stores the error in $c->error. This
362             method should only be used to store fatal error messages.
363            
364             my @error = @{ $c->error };
365            
366             Add a new error.
367            
368             $c->error('Something bad happened');
369            
370             =cut
371              
372             sub error {
373 3609     3609 1 59962     my $c = shift;
374 3609 100       58293     if ( $_[0] ) {
    50          
375 14 50       187         my $error = ref $_[0] eq 'ARRAY' ? $_[0] : [@_];
376 14 50       449         croak @$error unless ref $c;
377 14         126         push @{ $c->{error} }, @$error;
  14         222  
378                 }
379 0         0     elsif ( defined $_[0] ) { $c->{error} = undef }
380 3609   100     161080     return