File Coverage

blib/lib/CGI/Session/YAML.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package CGI::Session::YAML;
2              
3             =head1 NAME
4              
5             CGI::Session::YAML - A session-handling module that uses YAML for storage.
6              
7             =head1 SYNOPSIS
8              
9             use CGI::Session::YAML;
10             my $query = CGI::Session::YAML->new('/var/tmp/mysessiondir');
11              
12             $query->param(-name => 'foo', -value => 'bar');
13              
14             $query->commit();
15              
16             =head1 DESCRIPTION
17              
18             This module is a CGI module proxy that overrides the basic param handling
19             methods in the CGI module, and causes them to be saved in a YAML storage file
20             for reloading afterwards.
21              
22             The session id is stored in the CGI parameter .id, with a new one being
23             created if not supplied. The ID is a 128-bit UUID created via Data::UUID.
24              
25             The session is not saved until the commit() method is called. Conversely the
26             constructor will load an existing session file if there is one to load, based
27             on the session ID and the session directory. As the session directory does
28             default to the /tmp directory, supplying a different one is recommended.
29              
30             =cut
31              
32 1     1   21512 use YAML;
  0            
  0            
33             use CGI;
34             use Data::UUID;
35              
36             our @ISA = qw(CGI);
37             our $VERSION = 0.3;
38              
39             =head2 new
40              
41             This is the class constructor. It takes an optional parameter, which is the
42             session directory. It is highly recommended to provide one with the proper
43             permissions for your setup, as opposed to using the default of /tmp.
44              
45             The constructor will look in the session directory, and check for an .id CGI
46             parameter, and load $sessiondir/$id as its initial session, if it exists. If
47             .id does not exist, it will create a new session.
48              
49             =cut
50              
51             sub new
52             {
53             my $proto = shift;
54             my $sessiondir = shift || '/tmp';
55             my $class = ref($proto) || $proto;
56             my $self = CGI->new(@_);
57             $self->{paramshash} = {};
58             $self->{sessiondir} = $sessiondir;
59             $self->{sessionid} = $self->param('.id');
60             # sessionid may not cross directory boundaries, it must be a file.
61             if ($self->{sessionid} =~ m#/#)
62             {
63             die "sessionid cannot cross directory boundaries";
64             }
65             unless ($self->{sessionid})
66             {
67             my $u = Data::UUID->new();
68             $self->{sessionid} = lc $u->to_string($u->create);
69             $self->{sessionid} =~ s/-//g;
70             }
71              
72             $self->{sessionfile} = $self->{sessiondir} . '/' . $self->{sessionid};
73              
74             if (-f $self->{sessionfile})
75             {
76             $self->{paramshash} = YAML::LoadFile($self->{sessionfile});
77             foreach my $param (keys %{ $self->{paramshash} })
78             {
79             $self->param(-name => $param, -value => $self->{paramshash}{$param});
80             }
81             }
82              
83             foreach my $param ($self->param)
84             {
85             $self->{paramshash}{$param} = $self->param($param);
86             }
87              
88             # Rebless CGI horribly because it apparently doesn't inherit properly.
89             bless $self, $class;
90             return $self;
91             }
92              
93             =head2 param
94              
95             This is a proxy to CGI::param, but it intercepts CGI parameters being set so
96             that it may update storage.
97              
98             =cut
99              
100             sub param
101             {
102             my $self = shift;
103             my %args = ();
104             if ((@_) && (@_ % 2 == 0))
105             {
106             %args = @_;
107              
108             if ($args{-name})
109             {
110             $self->{paramshash}{$args{-name}} = $args{-value};
111             }
112             }
113             return $self->SUPER::param(@_);
114             }
115              
116             =head2 delete
117              
118             This is a proxy to CGI::delete, but it intercepts CGI parameters being deleted
119             so that it may update storage.
120              
121             =cut
122              
123             sub delete
124             {
125             my $self = shift;
126             if (@_)
127             {
128             delete $self->{paramshash}{$_[0]};
129             }
130             return $self->SUPER::delete(@_);
131             }
132              
133             =head2 delete_all
134              
135             This is a proxy to CGI::delete_all, but it intercepts CGI parameters being
136             deleted so that it may update storage.
137              
138             =cut
139              
140             sub delete_all
141             {
142             my $self = shift;
143             $self->{paramshash} = {};
144             return $self->SUPER::delete_all();
145             }
146              
147             =head2 commit
148              
149             This method causes the session file to be updated with the latest cached CGI
150             parameters.
151              
152             =cut
153              
154             sub commit
155             {
156             my $self = shift;
157             my $file = $self->{sessiondir} . '/' . $self->{sessionid};
158              
159             YAML::DumpFile($file, $self->{paramshash});
160             }
161              
162             =head1 AUTHOR
163              
164             Michael P. Soulier
165              
166             =head1 COPYRIGHT
167              
168             Copyright 2007 Michael P. Soulier. All rights reserved.
169              
170             This library is free software; you can redistribute it and/or
171             modify it under the same terms as Perl itself.
172              
173             =head1 SEE ALSO
174              
175             CGI, Data::UUID
176              
177             =cut