- Refactored get_action into get_action and get_actions
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Base.pm
1 package Catalyst::Base;
2
3 use strict;
4 use base qw/Catalyst::AttrContainer Class::Accessor::Fast/;
5
6 use Catalyst::Exception;
7 use NEXT;
8
9 __PACKAGE__->mk_classdata($_) for qw/_config _dispatch_steps/;
10
11 __PACKAGE__->_dispatch_steps( [qw/_BEGIN _AUTO _ACTION/] );
12
13 sub _DISPATCH : Private {
14     my ( $self, $c ) = @_;
15
16     foreach my $disp ( @{ $self->_dispatch_steps } ) {
17         last unless $c->forward($disp);
18     }
19
20     $c->forward('_END');
21 }
22
23 sub _BEGIN : Private {
24     my ( $self, $c ) = @_;
25     my $begin = ($c->get_actions( 'begin', $c->namespace))[-1];
26     return 1 unless $begin;
27     $begin->execute($c);
28     return !@{ $c->error };
29 }
30
31 sub _AUTO : Private {
32     my ( $self, $c ) = @_;
33     my @auto = $c->get_actions('auto', $c->namespace);
34     foreach my $auto (@auto) {
35         $auto->execute($c);
36         return 0 unless $c->state;
37     }
38     return 1;
39 }
40
41 sub _ACTION : Private {
42     my ( $self, $c ) = @_;
43     $c->action->execute($c);
44     return !@{ $c->error };
45 }
46
47 sub _END : Private {
48     my ( $self, $c ) = @_;
49     my $end = ($c->get_actions( 'end', $c->namespace))[-1];
50     return 1 unless $end;
51     $end->execute($c);
52     return !@{ $c->error };
53 }
54
55 =head1 NAME
56
57 Catalyst::Base - Catalyst Universal Base Class
58
59 =head1 SYNOPSIS
60
61     # lib/MyApp/Model/Something.pm
62     package MyApp::Model::Something;
63
64     use base 'Catalyst::Base';
65
66     __PACKAGE__->config( foo => 'bar' );
67
68     sub test {
69         my $self = shift;
70         return $self->{foo};
71     }
72
73     sub forward_to_me {
74         my ( $self, $c ) = @_;
75         $c->response->output( $self->{foo} );
76     }
77     
78     1;
79
80     # Methods can be a request step
81     $c->forward(qw/MyApp::Model::Something forward_to_me/);
82
83     # Or just methods
84     print $c->comp('MyApp::Model::Something')->test;
85
86     print $c->comp('MyApp::Model::Something')->{foo};
87
88 =head1 DESCRIPTION
89
90 This is the universal base class for Catalyst components
91 (Model/View/Controller).
92
93 It provides you with a generic new() for instantiation through Catalyst's
94 component loader with config() support and a process() method placeholder.
95
96 =head1 METHODS
97
98 =over 4
99
100 =item new($c)
101
102 =cut
103
104 sub new {
105     my ( $self, $c ) = @_;
106
107     # Temporary fix, some components does not pass context to constructor
108     my $arguments = ( ref( $_[-1] ) eq 'HASH' ) ? $_[-1] : {};
109
110     return $self->NEXT::new( { %{ $self->config }, %{$arguments} } );
111 }
112
113 # remember to leave blank lines between the consecutive =item's
114 # otherwise the pod tools don't recognize the subsequent =items
115
116 =item $c->config
117
118 =item $c->config($hashref)
119
120 =item $c->config($key, $value, ...)
121
122 =cut
123
124 sub config {
125     my $self = shift;
126     $self->_config( {} ) unless $self->_config;
127     if (@_) {
128         my $config = @_ > 1 ? {@_} : $_[0];
129         while ( my ( $key, $val ) = each %$config ) {
130             $self->_config->{$key} = $val;
131         }
132     }
133     return $self->_config;
134 }
135
136 =item $c->process()
137
138 =cut
139
140 sub process {
141
142     Catalyst::Exception->throw( message => ( ref $_[0] || $_[0] )
143           . " did not override Catalyst::Base::process" );
144 }
145
146 =back
147
148 =head1 SEE ALSO
149
150 L<Catalyst>.
151
152 =head1 AUTHOR
153
154 Sebastian Riedel, C<sri@cpan.org>
155 Marcus Ramberg, C<mramberg@cpan.org>
156 Matt S Trout, C<mst@shadowcatsystems.co.uk>
157
158 =head1 COPYRIGHT
159
160 This program is free software, you can redistribute it and/or modify it under
161 the same terms as Perl itself.
162
163 =cut
164
165 1;