Commit | Line | Data |
6166f03d |
1 | package Catalyst::Component::ACCEPT_CONTEXT; |
75f37967 |
2 | |
6166f03d |
3 | use warnings; |
75f37967 |
4 | use strict; |
ff05bc31 |
5 | use MRO::Compat; |
75f37967 |
6 | use Scalar::Util qw(weaken); |
6166f03d |
7 | |
8 | =head1 NAME |
9 | |
75f37967 |
10 | Catalyst::Component::ACCEPT_CONTEXT - Make the current Catalyst |
11 | request context available in Models and Views. |
12 | |
13 | =head1 VERSION |
14 | |
bf842f63 |
15 | Version 0.07 |
75f37967 |
16 | |
17 | =cut |
18 | |
bf842f63 |
19 | our $VERSION = '0.07'; |
75f37967 |
20 | |
21 | =head1 SYNOPSIS |
22 | |
23 | Models and Views don't usually have access to the request object, |
24 | since they probably don't really need it. Sometimes, however, having |
25 | the request context available outside of Controllers makes your |
26 | application cleaner. If that's the case, just use this module as a |
27 | base class: |
28 | |
29 | package MyApp::Model::Foobar; |
30 | use base qw|Catalyst::Component::ACCEPT_CONTEXT Catalyst::Model|; |
31 | |
32 | Then, you'll be able to get the current request object from within |
33 | your 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 | |
42 | Using this module is somewhat of a hack. Changing the state of your |
43 | objects on every request is a pretty braindead way of doing OO. If |
44 | you want your application to be brain-live, then you should use |
19ac5de9 |
45 | L<Catalyst::Component::InstancePerContext>. |
a10b37c1 |
46 | |
47 | Instead of doing this on every request (which is basically |
48 | what this module does): |
49 | |
50 | $my_component->context($c); |
51 | |
52 | It'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 | |
73 | Now you get a brand new object that lasts for a single request instead |
74 | of changing the state of an existing one on each request. This is |
75 | much cleaner OO design. |
76 | |
77 | The best strategy, though, is not to use the context inside your |
78 | model. It's best for your Controller to pull the necessary data from |
79 | the 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 | |
88 | This will make it Really Easy to test your components outside of |
89 | Catalyst, which is always good. |
90 | |
75f37967 |
91 | =head1 METHODS |
92 | |
93 | =head2 context |
94 | |
95 | Returns the current request context. |
96 | |
97 | =cut |
98 | |
99 | sub context { |
100 | return shift->{context}; |
101 | } |
102 | |
103 | =head2 ACCEPT_CONTEXT |
104 | |
105 | Catalyst calls this method to give the current context to your model. |
106 | You should never call it directly. |
107 | |
108 | Note that a new instance of your component isn't created. All we do |
109 | here is shove C<$c> into your component. ACCEPT_CONTEXT allows for |
110 | other behavior that may be more useful; if you want something else to |
111 | happen just implement it yourself. |
112 | |
113 | See L<Catalyst::Component> for details. |
114 | |
115 | =cut |
116 | |
117 | sub 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 | |
129 | Overridden to use initial application object as context before a request. |
130 | |
131 | =cut |
132 | |
133 | sub 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 | |
144 | Jonathan Rockway, C<< <jrockway at cpan.org> >> |
145 | |
a4e747a2 |
146 | Patches 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 | |
158 | Please report any bugs or feature requests to |
159 | C<bug-catalyst-component-accept_context at rt.cpan.org>, or through the web interface at |
160 | L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Catalyst-Component-ACCEPT_CONTEXT>. |
161 | I will be notified, and then you'll automatically be notified of progress on |
162 | your bug as I make changes. |
163 | |
164 | =head1 SUPPORT |
165 | |
166 | You can find documentation for this module with the perldoc command. |
167 | |
168 | perldoc Catalyst::Component::ACCEPT_CONTEXT |
169 | |
170 | You can also look for information at: |
171 | |
172 | =over 4 |
173 | |
174 | =item * Catalyst Website |
175 | |
176 | L<http://www.catalystframework.org/> |
177 | |
178 | =item * AnnoCPAN: Annotated CPAN documentation |
179 | |
180 | L<http://annocpan.org/dist/Catalyst-Component-ACCEPT_CONTEXT> |
181 | |
182 | =item * CPAN Ratings |
183 | |
184 | L<http://cpanratings.perl.org/d/Catalyst-Component-ACCEPT_CONTEXT> |
185 | |
186 | =item * RT: CPAN's request tracker |
187 | |
188 | L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Catalyst-Component-ACCEPT_CONTEXT> |
189 | |
190 | =item * Search CPAN |
191 | |
192 | L<http://search.cpan.org/dist/Catalyst-Component-ACCEPT_CONTEXT> |
193 | |
194 | =back |
195 | |
a4e747a2 |
196 | =head1 Source code |
197 | |
198 | The 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 | |
204 | Copyright 2007 Jonathan Rockway. |
205 | |
206 | This program is free software; you can redistribute it and/or modify it |
207 | under the same terms as Perl itself. |
6166f03d |
208 | |
209 | =cut |
210 | |
75f37967 |
211 | 1; # End of Catalyst::Component::ACCEPT_CONTEXT |