our $VERSION = '0.03';
our $AUTHORITY = 'cpan:STEVAN';
-use Plack::Util::Accessor qw( id expired _manager );
-
-sub fetch_or_create {
- my($class, $request, $manager) = @_;
-
- my($id, $session);
- if ($id = $manager->state->extract($request) and
- $session = $manager->store->fetch($id)) {
- return $class->new( id => $id, _stash => $session, _manager => $manager, _changed => 0 );
- } else {
- $id = $manager->state->generate($request);
- return $class->new( id => $id, _stash => {}, _manager => $manager, _changed=> 1 );
- }
-}
+use Plack::Util::Accessor qw( session options );
sub new {
- my ($class, %params) = @_;
- bless { %params } => $class;
+ my ($class, $env) = @_;
+ # NOTE: when you make a subclass, be sure to NEVER save $env in
+ # your hash. That will create a circular reference.
+ bless {
+ session => $env->{'psgix.session'},
+ options => $env->{'psgix.session.options'},
+ }, $class;
+}
+
+sub id {
+ my $self = shift;
+ $self->options->{id};
}
## Data Managment
sub dump {
my $self = shift;
- $self->{_stash};
+ $self->session;
}
sub get {
my ($self, $key) = @_;
- $self->{_stash}{$key};
+ $self->session->{$key};
}
sub set {
my ($self, $key, $value) = @_;
- $self->{_changed}++;
- $self->{_stash}{$key} = $value;
+ delete $self->options->{no_store};
+ $self->session->{$key} = $value;
}
sub remove {
my ($self, $key) = @_;
- $self->{_changed}++;
- delete $self->{_stash}{$key};
+ delete $self->options->{no_store};
+ delete $self->session->{$key};
}
sub keys {
my $self = shift;
- keys %{$self->{_stash}};
+ keys %{$self->session};
}
## Lifecycle Management
sub expire {
my $self = shift;
- $self->{_stash} = {};
- $self->expired(1);
-}
-
-sub commit {
- my $self = shift;
-
- if ($self->expired) {
- $self->_manager->store->cleanup($self->id);
- } else {
- $self->_manager->store->store($self->id, $self);
- }
-
- $self->{_changed} = 0;
-}
-
-sub is_changed {
- my $self = shift;
- $self->{_changed} > 0;
-}
-
-sub finalize {
- my ($self, $response) = @_;
-
- $self->commit if $self->is_changed || $self->expired;
- if ($self->expired) {
- $self->_manager->state->expire_session_id($self->id, $response);
- } else {
- $self->_manager->state->finalize($self->id, $response, $self);
+ for my $key ($self->keys) {
+ delete $self->session->{$key};
}
+ $self->options->{expire} = 1;
}
1;
=head1 SYNOPSIS
- use Plack::Session;
+ # Use with Middleware::Session
+ enable "Session", session_class => "Plack::Session";
- my $store = Plack::Session::Store->new;
- my $state = Plack::Session::State->new;
+ my $app = sub {
+ my $env = shift;
+ my $session = $env->{'plack.session'}; # not psgix.
- my $s = Plack::Session->new(
- store => $store,
- state => $state,
- request => Plack::Request->new( $env )
- );
+ $session->id;
+ $session->get($key);
+ $session->set($key, $value);
+ $session->remove($key);
+ $session->keys;
- # ...
+ $session->expire;
+ };
=head1 DESCRIPTION
=over 4
-=item B<new ( %params )>
+=item B<new ( $env )>
-The constructor expects keys in C<%params> for I<state>,
-I<store> and I<request>. The I<request> param is expected to be
-a L<Plack::Request> instance or an object with an equivalent
-interface.
+The constructor takes a PSGI request env hash reference.
=item B<id>
This is the accessor for the session id.
-=item B<state>
-
-This is expected to be a L<Plack::Session::State> instance or
-an object with an equivalent interface.
-
-=item B<store>
-
-This is expected to be a L<Plack::Session::Store> instance or
-an object with an equivalent interface.
-
=back
=head2 Session Data Management
These methods allows you to read and write the session data like
-Perl's normal hash. The operation is not synced to the storage until
-you call C<finalize> on it.
+Perl's normal hash.
=over 4
=item B<keys>
+=item B<session>, B<dump>
+
=back
=head2 Session Lifecycle Management
=over 4
-=item B<commit>
-
-This method synchronizes the session data to the data store, without
-waiting for the response final phase.
-
=item B<expire>
-This method can be called to expire the current session id. It marks
-the session as expire and call the C<cleanup> method on the C<store>
-and the C<expire_session_id> method on the C<state>.
-
-=item B<finalize ( $manager, $response )>
-
-This method should be called at the end of the response cycle. It will
-call the C<store> method on the C<store> and the C<expire_session_id>
-method on the C<state>. The C<$response> is expected to be a
-L<Plack::Response> instance or an object with an equivalent interface.
+This method can be called to expire the current session id.
=back