File Coverage

blib/lib/Object/Generic/Session.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package Object::Generic::Session;
2             #
3             # Object::Generic::Session is session object for
4             # web applications that defines a get/set interface
5             # consistent with Object::Generic and Class::DBI.
6             #
7             # See the end of this file for the documentation.
8             #
9             # $Id: Session.pm 404 2005-11-29 19:53:19Z mahoney $
10              
11 1     1   28240 use strict;
  1         3  
  1         35  
12 1     1   5 use warnings;
  1         3  
  1         30  
13 1     1   5 use base qw( Session Object::Generic );
  1         6  
  1         2411  
14 1     1   13543 use Object::Generic::False qw(false);
  1         3  
  1         40  
15 1     1   460 use Apache::Cookie;
  0            
  0            
16              
17             our $VERSION = 0.12;
18              
19             #
20             # Usage: $session = new Object::Generic::Session(
21             # session_config =>
22             # { Store => 'MySQL', # SQLite, here, but it still wants this.
23             # DataSource => "dbi:SQLite:dbname=$databasefile",
24             # Lock => 'Null',
25             # Generate => 'MD5',
26             # Serialize => 'Base64',
27             # },
28             # expires => '+8h',
29             # cookie_name => 'put some sort of site identifier here'
30             # )
31             sub new {
32             my $class = shift;
33             my %args = @_;
34             my $session_config = $args{session_config}
35             or return "Oops - no session_config given.";
36             my $cookie_name = $args{cookie_name}
37             or return "Oops - 'cookie_name' not defined.";
38             my $expires = $args{expires} || '+8h';
39             my $path = $args{path} || '/';
40             my $r = Apache->request; # See Apache::Cookie docs.
41              
42             # If the browser sent a cookie, get the session ID from it, and
43             # use that ID to fetch the session data from the database.
44             # If we didn't get a cookie, or if the matching session
45             # can't be found in the database, start a new session.
46             # Tell Apache to set a cookie in the HTTPD headers with
47             # the session ID regardless.
48             my $cookies = Apache::Cookie->fetch;
49             my $cookie = $cookies ? $cookies->{$cookie_name} : undef;
50             my $cookie_value = $cookie ? $cookie->value : undef;
51             my $self = Session->new($cookie_value, %$session_config)
52             || Session->new(undef, %$session_config);
53             if (not $self){
54             return 'Oops: unable to create a session with given session_config.';
55             }
56             ## May be used to count invocations for debuggin.
57             # if ($self->get('__access_count'){
58             # $self->set('__access_count' => 1+$self->get('__access_count'))
59             # }
60             # else {
61             # $self->set('__access__count' => 0);
62             # }
63             Apache::Cookie->new($r,
64             -name => $cookie_name,
65             -value => $self->session_id,
66             -expires => $expires,
67             -path => $path,
68             )->bake;
69             return bless $self, $class;
70             }
71              
72             # Session has its own 'get' and 'exists' methods,
73             # which are the ones found first in the inheritance chain.
74             # Here the behavior is changed slightly by returning
75             # an Object::Generic::False when the key doesn't exist.
76             sub get {
77             my $self = shift;
78             my ($key) = @_;
79             return false unless $self->exists($key);
80             return $self->SUPER::get($key);
81             }
82              
83             # This fixes what seemed like a bug to me in how sessions were handled.
84             #
85             # If data within the session, say $session->foo->bar->baz
86             # change without anything in $session->{} itself changing,
87             # Session.pm won't know that the session needs to be written
88             # back out to the database, and thus the changes may not be saved.
89             #
90             # So, I force any 'set' operation to mark this session as modified.
91             # I'm not sure why this isn't the default.
92             # See Apache::Session's code for this make_modified routine.
93             sub set {
94             my $self = shift;
95             $self->make_modified();
96             return $self->SUPER::set(@_);
97             }
98              
99             1;
100              
101             __END__