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