Bump versions, changelog for release
[catagits/Catalyst-Component-ACCEPT_CONTEXT.git] / lib / Catalyst / Component / ACCEPT_CONTEXT.pm
CommitLineData
6166f03d 1package Catalyst::Component::ACCEPT_CONTEXT;
75f37967 2
6166f03d 3use warnings;
75f37967 4use strict;
ff05bc31 5use MRO::Compat;
75f37967 6use Scalar::Util qw(weaken);
6166f03d 7
8=head1 NAME
9
75f37967 10Catalyst::Component::ACCEPT_CONTEXT - Make the current Catalyst
11request context available in Models and Views.
12
13=head1 VERSION
14
bf842f63 15Version 0.07
75f37967 16
17=cut
18
bf842f63 19our $VERSION = '0.07';
75f37967 20
21=head1 SYNOPSIS
22
23Models and Views don't usually have access to the request object,
24since they probably don't really need it. Sometimes, however, having
25the request context available outside of Controllers makes your
26application cleaner. If that's the case, just use this module as a
27base class:
28
29 package MyApp::Model::Foobar;
30 use base qw|Catalyst::Component::ACCEPT_CONTEXT Catalyst::Model|;
31
32Then, you'll be able to get the current request object from within
33your model:
34
35 sub do_something {
36 my $self = shift;
37 print "The current URL is ". $self->context->req->uri->as_string;
38 }
39
a10b37c1 40=head1 WARNING WARNING WARNING
41
42Using this module is somewhat of a hack. Changing the state of your
43objects on every request is a pretty braindead way of doing OO. If
44you want your application to be brain-live, then you should use
19ac5de9 45L<Catalyst::Component::InstancePerContext>.
a10b37c1 46
47Instead of doing this on every request (which is basically
48what this module does):
49
50 $my_component->context($c);
51
52It's better to do something like this:
9087ba50 53
a10b37c1 54 package FooApp::Controller::Root;
55 use base 'Catalyst::Controller';
56 use Moose;
9087ba50 57
a10b37c1 58 with 'Catalyst::Component::InstancePerContext';
59 has 'context' => (is => 'ro');
9087ba50 60
a10b37c1 61 sub build_per_context_instance {
62 my ($self, $c, @args) = @_;
63 return $self->new({ context => $c, %$self, @args });
64 }
9087ba50 65
a10b37c1 66 sub actions :Whatever {
67 my $self = shift;
68 my $c = $self->context; # this works now
69 }
9087ba50 70
a10b37c1 71 1;
72
73Now you get a brand new object that lasts for a single request instead
74of changing the state of an existing one on each request. This is
75much cleaner OO design.
76
77The best strategy, though, is not to use the context inside your
78model. It's best for your Controller to pull the necessary data from
79the context, and pass it as arguments:
80
81 sub action :Local {
82 my ($self, $c) = @_;
83 my $foo = $c->model('Foo');
84 my $quux = $foo->frobnicate(baz => $c->request->params->{baz});
85 $c->stash->{quux} = $quux;
86 }
87
88This will make it Really Easy to test your components outside of
89Catalyst, which is always good.
90
75f37967 91=head1 METHODS
92
93=head2 context
94
95Returns the current request context.
96
97=cut
98
99sub context {
100 return shift->{context};
101}
102
103=head2 ACCEPT_CONTEXT
104
105Catalyst calls this method to give the current context to your model.
106You should never call it directly.
107
108Note that a new instance of your component isn't created. All we do
109here is shove C<$c> into your component. ACCEPT_CONTEXT allows for
110other behavior that may be more useful; if you want something else to
111happen just implement it yourself.
112
113See L<Catalyst::Component> for details.
114
115=cut
116
117sub ACCEPT_CONTEXT {
118 my $self = shift;
119 my $context = shift;
120
121 $self->{context} = $context;
122 weaken($self->{context});
ff05bc31 123
16beaa34 124 return $self->maybe::next::method($context, @_) || $self;
75f37967 125}
126
127=head2 COMPONENT
128
129Overridden to use initial application object as context before a request.
130
131=cut
132
133sub COMPONENT {
134 my $class = shift;
135 my $app = shift;
136 my $args = shift;
137 $args->{context} = $app;
138 weaken($args->{context}) if ref $args->{context};
16beaa34 139 return $class->maybe::next::method($app, $args, @_);
75f37967 140}
141
142=head1 AUTHOR
143
144Jonathan Rockway, C<< <jrockway at cpan.org> >>
145
a4e747a2 146Patches contributed and maintained by:
147
148=over
149
150=item Rafael Kitover (Caelum)
151
152=item Tomas Doran (t0m) C<< <bobtfish@bobtfish.net> >>
153
154=back
155
75f37967 156=head1 BUGS
157
158Please report any bugs or feature requests to
159C<bug-catalyst-component-accept_context at rt.cpan.org>, or through the web interface at
160L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Catalyst-Component-ACCEPT_CONTEXT>.
161I will be notified, and then you'll automatically be notified of progress on
162your bug as I make changes.
163
164=head1 SUPPORT
165
166You can find documentation for this module with the perldoc command.
167
168 perldoc Catalyst::Component::ACCEPT_CONTEXT
169
170You can also look for information at:
171
172=over 4
173
174=item * Catalyst Website
175
176L<http://www.catalystframework.org/>
177
178=item * AnnoCPAN: Annotated CPAN documentation
179
180L<http://annocpan.org/dist/Catalyst-Component-ACCEPT_CONTEXT>
181
182=item * CPAN Ratings
183
184L<http://cpanratings.perl.org/d/Catalyst-Component-ACCEPT_CONTEXT>
185
186=item * RT: CPAN's request tracker
187
188L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Catalyst-Component-ACCEPT_CONTEXT>
189
190=item * Search CPAN
191
192L<http://search.cpan.org/dist/Catalyst-Component-ACCEPT_CONTEXT>
193
194=back
195
a4e747a2 196=head1 Source code
197
198The source code for this project can be found at:
199
200 git://git.shadowcat.co.uk/catagits/Catalyst-Component-ACCEPT_CONTEXT
201
75f37967 202=head1 COPYRIGHT & LICENSE
203
204Copyright 2007 Jonathan Rockway.
205
206This program is free software; you can redistribute it and/or modify it
207under the same terms as Perl itself.
6166f03d 208
209=cut
210
75f37967 2111; # End of Catalyst::Component::ACCEPT_CONTEXT