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