Merged in patch from IKEGAMI, to behave gracefully with other session state modules
[catagits/Catalyst-Plugin-Session-State-Stash.git] / lib / Catalyst / Plugin / Session / State / Stash.pm
CommitLineData
642b19cf 1package Catalyst::Plugin::Session::State::Stash;
0c46f6c5 2use Moose;
3use 5.008;
642b19cf 4use MRO::Compat;
0c46f6c5 5use namespace::autoclean;
6
7extends 'Catalyst::Plugin::Session::State';
642b19cf 8
08a504c0 9our $VERSION = "0.13";
642b19cf 10
0c46f6c5 11has _deleted_session_id => ( is => 'rw' );
12has _prepared => ( is => 'rw' );
642b19cf 13
e08a2683 14sub _stash_key_components {
642b19cf 15 my ($c) = @_;
643399c7 16 my $config = $c->_session_plugin_config;
effd6244 17 return ($config->{stash_delim}) ?
18 split $config->{stash_delim}, $config->{stash_key} :
19 $config->{stash_key};
642b19cf 20}
21
22sub _get_session {
23 my ($c) = @_;
e08a2683 24 # This turns the list of path components into a nested tree of hashrefs for obtaining info/storing in: 123/456 = {123}->{456}
25 my $ref = $c->stash;
26 $ref = ($ref->{$_} ||= {}) foreach $c->_stash_key_components;
27 $ref;
642b19cf 28}
29
30sub _set_session {
31 my ( $c,$key,$value) = @_;
e08a2683 32 $c->_get_session->{$key} = $value;
642b19cf 33}
34
35sub setup_session {
36 my $c = shift;
07571d90 37
38 $c->maybe::next::method(@_);
39
643399c7 40 $c->_session_plugin_config->{stash_key} ||= '_session';
642b19cf 41}
42
43sub prepare_action {
44 my $c = shift;
45 my $id = $c->get_session_id;
46 $c->_prepared(1);
47 if ( $id ) {
48 $c->sessionid( $id );
49 }
50 $c->maybe::next::method( @_ );
51}
52
53sub get_session_id {
54 my $c = shift;
55 if(!$c->_deleted_session_id and my $session = $c->_get_session) {
56 my $sid = $session->{id};
57 return $sid if $sid;
58 }
59 $c->maybe::next::method(@_);
60}
61
62sub set_session_id {
63 my ( $c, $sid ) = @_;
64 $c->_set_session(id => $sid);
65 $c->maybe::next::method($sid);
66}
67
68sub get_session_expires {
69 my $c = shift;
70 my $session = $c->_get_session;
71 defined $session->{expires} ? $session->{expires} : undef;
72}
73
74sub set_session_expires {
75 my ( $c, $expires ) = @_;
642b19cf 76 $c->_set_session(expires => time() + $expires);
77 $c->maybe::next::method($expires)
78}
79
80sub delete_session_id {
81 my ($c, $sid ) = @_;
82 $c->_deleted_session_id(1);
e08a2683 83 #Empty the tip
84 %{$c->_get_session} = ();
642b19cf 85 $c->maybe::next::method($sid);
86}
87
88
891;
90__END__
91
92=pod
93
94=head1 NAME
95
96Catalyst::Plugin::Session::State::Stash - Maintain session IDs using the stash
97
98=head1 SYNOPSIS
99
100 use Catalyst qw/Session Session::State::Stash Session::Store::Foo/;
101
102=head1 DESCRIPTION
103
104An alternative state storage plugin that allows you some more flexibility in
105dealing with session storage. This plugin loads and saves the session ID from
106and to the stash.
107
108=head1 METHODS
109
110=over 4
111
112=item delete_session_id
113
114Deletes the session. Unfortunately I've been unable to squash a bug that will
115stop you from opening a new session in the same execution, however.
116Patches welcome!
117
118=item get_session_id
119
120Gets the current session id.
121
122=item set_session_id
123
124Sets the session id to the C<shift>.
125
126=item get_session_expires
127
128Gets when the current session expires.
129
130=item set_session_expires
131
132Sets how many seconds from now the session should expire.
133
134=back
135
136=head1 EXTENDED METHODS
137
138=over 4
139
140=item prepare_action
141
142Loads the id off the stash.
143
144=item setup_session
145
146Defaults the C<stash_key> parameter to C<_session>.
147
148=back
149
150=head1 CONFIGURATION
151
152=over 4
153
154=item stash_key
155
156The name of the hash key to use. Defaults to C<_session>.
157
e08a2683 158=item stash_delim
159
160If present, splits stash_key at this character to nest. E.g. delim of '/'
161and key of '123/456' will store it as $c->stash->{123}->{456}
162
642b19cf 163=item expires
ff999ad1 164
642b19cf 165How long the session should last in seconds.
166
167=back
168
169For example, you could stick this in MyApp.pm:
170
effd6244 171 __PACKAGE__->config( 'Plugin::Session' => {
642b19cf 172 stash_key => 'session_id',
173 });
174
175=head1 BUGS
176
177You can't delete a session then create a new one. If this is important to you,
178patches welcome. It is not important to me and fixing this for completeness
179is pretty low on my list of priorities.
180
181=head1 CAVEATS
182
183Manual work may be involved to make better use of this.
184
185If you are writing a stateful web service with
ff999ad1 186L<Catalyst::Plugin::Server::XMLRPC>, you will probably only have to deal with
642b19cf 187loading, as when saving, the ID will already be on the stash.
188
189=head1 SEE ALSO
190
191L<Catalyst>, L<Catalyst::Plugin::Session>, L<Catalyst::Plugin::Session::State>,
192L<Catalyst::Plugin::Session::State::Cookie> (what you probably want).
193
194=head1 AUTHORS
195
196James Laver E<lt>perl -e 'printf qw/%s@%s.com cpan jameslaver/'E<gt>
197
198=head1 CONTRIBUTORS
199
200This module is derived from L<Catalyst::Plugin::Session::State::Cookie> code.
201
202Thanks to anyone who wrote code for that.
203
e08a2683 204Thanks to Kent Fredric for a patch for nested keys
205
642b19cf 206=head1 COPYRIGHT
207
208This program is free software, you can redistribute it and/or modify it
209under the same terms as Perl itself.
210
211=cut
212