- Move config stuff etc. out into Catalyst::Component; Catalyst::Base for things...
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Base.pm
CommitLineData
fc7ec1d9 1package Catalyst::Base;
2
3use strict;
158c88c0 4use base qw/Catalyst::Component Catalyst::AttrContainer Class::Accessor::Fast/;
b7783788 5
a2f2cde9 6use Catalyst::Exception;
91d4abc5 7use Catalyst::Utils;
8use Class::Inspector;
fc7ec1d9 9use NEXT;
10
158c88c0 11__PACKAGE__->mk_classdata($_) for qw/_dispatch_steps/;
1143712c 12
0bbb5a1f 13__PACKAGE__->_dispatch_steps( [qw/_BEGIN _AUTO _ACTION/] );
ac733264 14
0bbb5a1f 15sub _DISPATCH : Private {
ba599d1c 16 my ( $self, $c ) = @_;
1143712c 17
0bbb5a1f 18 foreach my $disp ( @{ $self->_dispatch_steps } ) {
1143712c 19 last unless $c->forward($disp);
ba599d1c 20 }
21
1143712c 22 $c->forward('_END');
23}
fc7ec1d9 24
0bbb5a1f 25sub _BEGIN : Private {
1143712c 26 my ( $self, $c ) = @_;
a9dc674c 27 my $begin = ($c->get_actions( 'begin', $c->namespace))[-1];
1143712c 28 return 1 unless $begin;
a9dc674c 29 $begin->execute($c);
0bbb5a1f 30 return !@{ $c->error };
1143712c 31}
ba599d1c 32
0bbb5a1f 33sub _AUTO : Private {
1143712c 34 my ( $self, $c ) = @_;
a9dc674c 35 my @auto = $c->get_actions('auto', $c->namespace);
1143712c 36 foreach my $auto (@auto) {
a9dc674c 37 $auto->execute($c);
1143712c 38 return 0 unless $c->state;
ba599d1c 39 }
1143712c 40 return 1;
41}
ba599d1c 42
0bbb5a1f 43sub _ACTION : Private {
1143712c 44 my ( $self, $c ) = @_;
45 $c->action->execute($c);
0bbb5a1f 46 return !@{ $c->error };
1143712c 47}
ba599d1c 48
0bbb5a1f 49sub _END : Private {
1143712c 50 my ( $self, $c ) = @_;
a9dc674c 51 my $end = ($c->get_actions( 'end', $c->namespace))[-1];
1143712c 52 return 1 unless $end;
a9dc674c 53 $end->execute($c);
0bbb5a1f 54 return !@{ $c->error };
ba599d1c 55}
d70195d8 56
91d4abc5 57sub action_namespace {
58 my ( $self, $c ) = @_;
59 return
60 Catalyst::Utils::class2prefix(
61 ref $self, $c->config->{case_sensitive} ) || '';
62}
63
64sub register_actions {
65 my ( $self, $c ) = @_;
66 my $class = ref $self || $self;
67 my $namespace = $self->action_namespace( $c );
68 my %methods;
69 $methods{$self->can($_)} = $_ for @{Class::Inspector->methods($class)||[]};
70 foreach my $cache (@{$self->_action_cache}) {
71 my $code = $cache->[0];
72 my $method = $methods{$code};
73 next unless $method;
74 my $attrs = $self->_parse_attrs(@{$cache->[1]});
75 if ($attrs->{Private} && ( keys %$attrs > 1 ) ) {
76 $c->log->debug( 'Bad action definition "'
77 . join( ' ', @{$cache->[1]} )
78 . qq/" for "$class->$method"/ )
79 if $c->debug;
80 next;
81 }
82 my $reverse = $namespace ? "$namespace/$method" : $method;
83 my $action = Catalyst::Action->new(
84 {
85 name => $method,
86 code => $code,
87 reverse => $reverse,
88 namespace => $namespace,
89 class => $class,
90 attributes => $attrs,
91 }
92 );
93 $c->dispatcher->register($c, $action);
94 }
95}
96
97sub _parse_attrs {
98 my ( $self, @attrs ) = @_;
99 my %attributes;
100 foreach my $attr (@attrs) {
101
102 # Parse out :Foo(bar) into Foo => bar etc (and arrayify)
103
104 if ( my ( $key, $value ) = ( $attr =~ /^(.*?)(?:\(\s*(.+)\s*\))?$/ ) ) {
105
106 if ( defined $value ) {
107 ( $value =~ s/^'(.*)'$/$1/ ) || ( $value =~ s/^"(.*)"/$1/ );
108 }
109 push( @{ $attributes{$key} }, $value );
110 }
111 }
112 return \%attributes;
113}
114
115
fc7ec1d9 116=head1 NAME
117
158c88c0 118Catalyst::Base - Catalyst Controller Base Class
fc7ec1d9 119
120=head1 SYNOPSIS
121
fc7ec1d9 122
123=head1 DESCRIPTION
124
fc7ec1d9 125
23f9d934 126=head1 METHODS
127
128=over 4
129
bea4160a 130=back
131
fc7ec1d9 132=head1 SEE ALSO
133
134L<Catalyst>.
135
136=head1 AUTHOR
137
138Sebastian Riedel, C<sri@cpan.org>
61b1e958 139Marcus Ramberg, C<mramberg@cpan.org>
ba599d1c 140Matt S Trout, C<mst@shadowcatsystems.co.uk>
fc7ec1d9 141
142=head1 COPYRIGHT
143
144This program is free software, you can redistribute it and/or modify it under
145the same terms as Perl itself.
146
147=cut
148
1491;