NAME

CGI::AutoForm::Session - Stateful CGI sessions

SYNOPSIS

use CGI::AutoForm::Session;


$session = new CGI::AutoForm::Session($query,[$user],[$dbh]);

$form = $session->next_form();

$form = $session->restart();

$form = $session->jump_form();

$form = $session->repeat_form();

$form = $session->summary_form();

$status = $session->status();

$normalized_query = $session->query();

$bool = $session->invalid_input();

Attribute Accessors/Modifiers

Get the values of these READ-ONLY attributes.

$query         = $session->query();

Get or set the values of these attributes.

$dbh           = $session->dbh();
$user          = $session->user();

DESCRIPTION

A virtual base class to help implement a CGI session across HTTP requests.

The basic idea is to define a set of forms using CGI::AutoForm, and cache them if desired (e.g. if using mod_perl). You then define a sequence that the forms will appear in the session depending on form names, user input, etc. Your CGI program propagates the session, form by form (by calling $session->next_form()) and user input is automatically verified at each stage according to the constraints you define with CGI::AutoForm. If a validation error occurs, the form is immediately presented again. At the end of the session, you have the option of presenting a summary screen where the user can confirm, edit or cancel the session. Editing previous input is allowed by jumping back to a previous form, yet all user input remains intact throughout the session.

Refer to CGI::AutoForm throughout this documentation.

DETAILS

This class relies on HIDDEN HTML form elements for persistence; why not something more sophisticated like IPC so that objects don't have to be reinstantiated? (e.g. PHP) Because with IPC you have to concern yourself with memory contraints from a heavily loaded web site or possible memory leaks from (perhaps rare) aberrant signals. HIDDEN form elements don't add or remove security concerns; a CGI session can only be as secure as the HTTP protocol that underlies it. If security is an issue, use HTTPS or equivalent and be consistent for the duration of the session.

A disadvantage of this approach is that data passed back and forth via HIDDEN fields need to be re-validated, but this should be done with the final summary form in any case.

Enough blabber!

Subclassing

You implement a session by subclassing this module. The following methods are expected to be overridden:

_init
$success = $session->_init();

This is called during construction and allows any class-specific initialization to occur (you can also override new() and chain up). With mod_perl I like to use this method to create all my forms and cache them when the very first object is created (of course, if any definitions of the form change in the database, I have to restart apache). Always give the form name to the contructor of form objects.

Only the form structure should ever be cached; form objects should be void of any user-specific data. By using/overriding next_form() and/or fetch_form() you can effectively cache forms and alter their structure or content during session runtime. An important distinction is made here between form structure and session-specific forms which may be customized according to user input or have user content. For security reasons, user input should never be cached with this class.

assign_forms
$success = $session->assign_forms();

If you are caching forms, the {forms} attribute must be assigned in this method. It will be a hashref of form_name => $form object pairs. All cached forms must be assigned a name. If you are not caching forms, or if your forms are created completely on-the-fly, you must override fetch_form(). See _init for a discussion of form caching.

_next_form
$form = $session->_next_form();

Not to be confused with next_form() This is where you direct the session by returning a form object according to a sequence of forms you define along with current and previous session information in state machine fashion. A few conventions are available to help guide you.

query() returns the web server response query string structured in a form acceptable to CGI::AutoForm::prepare() which was passed in during construction. See also CGI::AutoForm::format_query() for an even more useful structure.

recent_form_name() - this will return the most recently submitted form name.

start_form_name() - returns the name of the form that was first used in this session. In order for this to work this method should be called when the start form is first returned from _next_form() e.g., include this line somewhere in your subclass:

$self->start_form_name($this_is_the_first_form_of_this_session);

Note that recent_form_name() and start_form_name() use the name of your subclass as a unique identifier in the unlikely event that 2 or more sessions happen to bleed into each other. It does this in a case-insensitive manner and may cause problems if 2 classes have the same name that differ only by case.

verify_callback
$sub = $session->verify_callback();

This will be called during query validation (invalid_input) and the return value (if not undef()) must be a reference to a subroutine (callback) that will be passed to CGI::AutoForm::validate_query().

METHODS

new (constructor)
$session = new CGI::AutoForm::Session($query,[$user],[$dbh]);

Create a new session object with a structured query string (see CGI::AutoForm::prepare for the structure), and optional: $user - a username for restricted forms and $dbh - a valid database handle.

$query is immediately passed through CGI::AutoForm::normalize_query(). $user and $dbh may be convenient for subclasses.

Return undef if error.

status
$status = $session->status([$status]);

To advise your CGI program (or mod_perl handler) the following default status indicators apply to the form returned from next_form(). You can override them as appropriate.

'CONTINUE' - The form is a continuation in a sequence of forms.

'REPEAT' - The form is a repeat of the previous form (most likely because it had user input validation errors).

'JUMP' - See set by calling jump_form().

'SUMMARY' - A summary of all previous forms in the session.

query
$normalized_query = $session->query();

Return a normalized form of $query passed to the constructor. (See CGI::AutoForm::normalize_query())

invalid_input
$bool = $session->invalid_input();

Validates user input via CGI::AutoForm::validate_query(). May return the same form if the input elements can't be verified with VALID_ERROR attrs set for each field in error. Otherwise, return false if validation was successful.

next_form
$form = $session->next_form();

Validates current form submission using the query structure given in the constructor (if any). May return the same form if the input elements can't be verified with VALID_ERROR attrs set for each field in error. Otherwise the next form in the session is returned.

Refer to CGI::AutoForm for usage of $form.

restart
$form = $session->restart();

Return the very first form of this session with all user input intact.

jump_form
$form = $session->jump_form();

Jump back to a form previously encountered in this session with all user input intact.

repeat_form
$form = $session->repeat_form();

Return the most recently submitted form with all user input intact.

fetch_form
$form = $session->fetch_form($form_name);

Return the $form object indentified with $form_name.

prepare_form
$form = $session->prepare_form($form);

Call the prepare method on $form passing in $session->{query}.

summary_form
$form = $session->summary_form();

Return a form that contains all data groups of every form submitted in this session. This could be lengthy so you may want to customize the default layout of CGI::AutoForm.

The form data will be readonly but all data will be available on submission through hidden fields. Typically the user will have the chance to reject the data and the session would continue at the beginning by calling restart().

NOTE: Data from the summary form should be re-validated.

BUGS

No known bugs.

SEE ALSO

CGI::AutoForm

AUTHOR

Reed Sandberg, <reed_sandberg Ó’ yahoo>

COPYRIGHT AND LICENSE

Copyright (C) 2000-2007 Reed Sandberg

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

The full text of the license can be found in the LICENSE file included with this module.

4 POD Errors

The following errors were encountered while parsing the POD:

Around line 164:

You forgot a '=back' before '=head1'

Around line 167:

'=item' outside of any '=over'

Around line 545:

You forgot a '=back' before '=head1'

Around line 555:

Non-ASCII character seen before =encoding in 'Ó’'. Assuming CP1252