get_data()
- fetch raw inputget_action()
- what are we supposed to do with this data?do()
- perform the requested actiondo_db()
- perform the do()
tasks that directly touch the databasedo_update()
- perform an automatic update from a formdo_insert()
- perform an automatic insert from a formdo_search()
- perform an automatic search of a tableparse(%data)
- decode form dataformpush()
- push new data onto the end of the formvalidate()
- validate form datavalidate_record($table,$datahash)
- validate a datahashvalidate_column($table,$column,$datum)
- validate a column valuevalidate_datatype($type,$datum)
- validate a data valuevalidate_language($text,@forbidden)
- validates that $text uses ``clean'' languagemake(%options)
- build a completely self-contained formmake_form_buttons()
edit($table,$record,$hide,$show,$extra)
append($table,$record,$hide,$show,$extra)
search_query($table,$hide,$show,$extra)
input_record($opt)
- make labels and input tags for a whole recordinput_column(%opt)
- make the input tag(s)
for a database columninput_exsite(%opt)
- make the input tag(s)
for an ExSite datatypeinput_html(%opt)
- generate a single HTML input taguse_wysiwyg()
- check if the client supports WYSIWYG editinginput_htmleditor(%opt)
- place an HTML editor into a formeditor_javascript($section_id)
The Form class provides a variety of tools for composing HTML forms, reading and parsing form input, and automatically performing standard database operations (updates, inserts, searches) on forms that correspond to database records.
There are two groups of methods in this class: (1) form processing methods, and (2) form composition methods.
The form processing methods are mostly for processing forms that
represent database records; if these forms are built using the
input_record()
method (below), then they can be automatically
processed (read, parsed, validated, and submitted to the database)
by Form methods. In other words, you do not need to write the
script that accepts the form data, in simple cases.
For instance, you can create a form as follows:
my $form = new ExSite::Form;
print $form->make({table=>"my_db_table",...});
This same form can be processed as follows:
$form->do;
Note that make()
will automatically set the method, action, and
encoding type, so that no form processing code need be written.
Additionally, the Form class inherits from the Report, DB, and SQL (or other database driver) classes, and includes all of their functionality.
get_data()
- fetch raw inputThis method retrieves the form input and parses it (assuming it comes
from input_record
). It returns the total length of the input data.
get_action()
- what are we supposed to do with this data?This method figures out what to do with the data, by either reading the action field, or guessing based on the data. (Forms that specify primary keys are presumed to be updates; otherwise they are presumed to be inserts.)
Valid actions are ``insert'', ``update'', ``search''.
do()
- perform the requested actiondo()
executes the action suggested by get_action()
.
First, however, it checks the submit_action, to make sure the user didn't cancel the form. It also guesses a reasonable reply page, or uses the reply argument provided by the form.
For updates and inserts, do performs a validation check on the form data,
by calling validate()
. Any validation problems will prevent the
action from proceeding.
do_db()
- perform the do()
tasks that directly touch the databasedo_db()
skips the control-flow logic of form processing (dealing with
cancels, determining the reply page, reporting results), and directly
invokes the db interaction methods. This is handy if a non-generic control
program is handling high-level form processing.
do_update()
- perform an automatic update from a formIn cases where do()
decides to update the database, it does so by
calling do_update()
.
do_insert()
- perform an automatic insert from a formIn cases where do()
decides to insert a record into the database,
it does so by calling do_insert()
.
do_search()
- perform an automatic search of a tableIn cases where do()
decides to search a table in the database,
it does so by calling do_search()
. Searches are done by looking
for records that contain all of the provided values (ie. there is an
impled logical AND of the fields); records are taken as matches if
they contain the provided values as substrings.
parse(%data)
- decode form dataParse does more than the usual URL-decoding of form data. It also:
The parsed data is returned in a hash with the following structure:
$formdata{TABLE}->{ROW}->{COLUMN} = VALUE
where ``ROW'' is the primary key value (record ID) of the row. For inserts
in which the primary key is not yet defined, the ROW is _
for single-record
inserts, or _n
where n = 1,2,3,... for multi-record inserts.
If you rely on the Form class to automatically parse the form data, this
data structure will be stored in the Form object in $this-
{form}>.
There are 2 methods for encoding the table/row information in the form:
Method 1 places hidden, encrypted table/record markers into the form data. The markers are named "R[n]_mark" where [n] is some integer to identify the record. All inputs beginning with "R[n]_[column]" are attached to that record. This method is more secure because it is difficult to spoof invalid table and record IDs. It also works better with Javascript.
Method 2 encodes the table and record directly into each input name:
table#record_id#column
. The record_id
can be null, or ``_'' for a
simple insert, or ``_[n]'' for multiple distinct inserts. This method
has some security concerns, since the table and record IDs could be
tampered with by an attacker. Exsite does attempt to trap such
tampering, but the security logic is simple, and may not be sufficient
for certain situations/applications. It is best avoid method 2 on
forms that are used by unauthenticated members of the general public.
The main advantage to Method 2 is that forms can easily be hand-coded.
formpush()
- push new data onto the end of the formformpush()
is used to manually add new data items onto the form,
after the form data has already been parsed. This is typically used
by handlers and wizards to place extra data into the form after the
form has been submitted.
The new data is only added to the {form} attribute, not to the raw form data, nor to the input object. It is always added to the end of the form.
All of the validation routines return error messages (either single, or an array) if invalid data is found, or undef/empty array if no invalid data was detected.
Every datatype known to ExSite has its own validation regular expression. Validation of inputs conists of comparing the input value to this regular expression. ExSite determines the appropriate datatype to compare to by looking up the table and column associated with the input field, in the DBmap.
Additional validations that are performed incluide:
Note: The validation routines are automatically invoked by do()
.
validate()
- validate form dataValidate operates on the results of parse()
that were stored in the
Form object. It determines the validity of all form data that was
entered, as well as detecting missing required data.
validate_record($table,$datahash)
- validate a datahashvalidate_record()
validates the values in the passed $datahash
,
returning an array of error messages for values that do not correspond
to the accepted values for the given column. It determines the
validity of all data present in the datahash, as well as detecting
missing required data. It can be called directly, without actually
processing a form.
The rules it follows are different depending on whether the record
is for an insert or an update; if the form action ($this-
{action}>)
is not defined either way, an insert will be assumed, which is more
restrictive.
validate_column($table,$column,$datum)
- validate a column valuevalidate_column()
validates a single value for a specific column in
the database. An error message is returned if the value does not
match expected values. undef
is returned if the datum validates
correctly. It can be called directly, without actually processing a
form.
validate_datatype($type,$datum)
- validate a data valuevalidate_datatype()
checks that a data value conforms to the
allowed values for a datatype. It returns an error message if not, or
undef
if valid. It can be called directly, without actually
processing a form.
validate_language($text,@forbidden)
- validates that $text uses ``clean'' languageIf the wordfilter
feature is enabled, this validation method will
be invoked automatically on any public text content (ie. all string,
text, and html columns that are readable at level 1 or lower).
If the wordfilter
action is reject, then the validation routine
will throw validation errors if bad words are detected. For other
actions (censor and semi-censor), the text will be altered, and
warnings thown instead. Warnings will pass validation, but may still
generate messages on screen. If the user is of a sufficiently high
level (3 by default), their content is trusted, and always generates
warnings rather than errors.
validate_language()
returns the (modified) text, plus a list of
error messages if validation has failed. For censoring actions, there
should be no errors (unless the wordfilter has not been configured
properly), while for non-censoring actions, the text should not be
modified. It is the caller's responsibility to replace the original
text with the modified text.
The list of forbidden words is taken from a config file, by default
conf/badwords.txt
. If the wordfilter
feature is turned off,
this method will do nothing using this dictionary of forbidden words.
However, you can still invoke this method directly for special cases,
and provide your own list of forbidden words after the text parameter.
The form construction methods are used to compose HTML forms that are compatible with the form processing methods, above. Developers can redirect these forms to their own processing methods, but by default they will direct themselves to the automatic-processing methods.
make(%options)
- build a completely self-contained formmake()
builds forms for inserting or updating records into the
database, or for conducting searches on particular database tables.
By default, the form automatically sets its action so that it will
be automatically processed, executed, and the user will be returned
to an appropriate page when done.
Make a blank form to add a new record: $form->make(table=>$table_name)
Make a form to add a new record, prefilled with defaults : $form->make(table=>$table_name,data=>$datahash)
Make a form to update an existing record: $form->make(table=>$table_name,record=>$record_id)
Make a form to search a table: $form->make(table=>$table_name,search=>1)
make()
optionstable
, then a corresponding
array of record IDs should be passed here. This parameter can be left off
or set to undef
for inserts.
reply
'') to
go to after the form is processed.
doform.cgi
, which simply executes the automatic
form processing methods detailed above. A custom form processing URL
can be specified here instead.
ref to a datahash containing presets/defaults for the form.
debug.cgi
, which simply
displays the form contents to the developer, without processing the data.
make_form_buttons()
This generates standard submit, reset, and cancel buttons for a form.
It does not depend on make()
and may be invoked by any form. Note
that ``Cancel'' submits the form, but sets the submit_method
form
parameter to ``Cancel''. The form processing routine should check for
this value, before processing the form.
edit($table,$record,$hide,$show,$extra)
This is a wrapper for make()
that generates a form to edit an
existing record.
append($table,$record,$hide,$show,$extra)
This is a wrapper for make()
that generates a form to insert a new record.
search_query($table,$hide,$show,$extra)
This is a wrapper for make()
that generates a form to search a table.
input_record($opt)
- make labels and input tags for a whole recordGenerates the input labels and tags corresponding to a database record.
$opt
is a ref to an option hash:
table
record
data
hide
show
group
group
parameters works like show
, but for groups of columns.
input_record()
includes security checks to determine whether the
user is permitted to read/write each field. The corresponding inputs
are not generated if the checks indicate otherwise.
input_column(%opt)
- make the input tag(s)
for a database columnGenerates the HTML input tag(s)
corresponding to a single database
column. %opt
is an option hash (not a ref, as in input_record()
).
The input label is not generated.
For some datatypes, a single column may result in multiple input
fields (eg. dates, which prompt for year, month, and day separately.)
In cases where multipart input fields are generated, ExSite appends
a part marker to the input field name, eg. input_name#part
. It is
the responsibility of the decoding routines to patch these parts
back together into a single input value. The automatic form processing
tools above do this for you.
Options:
table
column
record
value
data
record
and
value
can be inferred, if not passed explicitly.
datatype
size
Note: no security checks are made on input_column()
; if using this
routine to generate custom forms, you must decide for yourself
whether the user is allowed to alter the column in question.
input_exsite(%opt)
- make the input tag(s)
for an ExSite datatypeGenerates the HTML input tag(s)
corresponding to an ExSite datatype.
This works similarly to input_column()
, except that we have no
database data or DBmap metadata to tell us about the column, so we
have to provide values, datatypes, input sizes, and other values manually.
date/datetime
time/datetime
set
foreign keys
encrypted fields
Note: no security checks are made on input_exsite()
; the form
processing routines are responsible for security validation of
the form data.
input_html(%opt)
- generate a single HTML input tagThis method outputs the tags for a single HTML form input.
Options:
use_wysiwyg()
- check if the client supports WYSIWYG editingReturns a true/false result, depending on whether the client browser identifies itself as one that supports the features of the ExSite HTML editor. The following browsers are supported:
input_htmleditor(%opt)
- place an HTML editor into a formThe editable content is specified as one of:
Other Options:
$config{htmleditor}
Only one instance of the editor may be used in a given form.
The editor downgrades to a simple textarea that edits raw HTML, if the client does not support the necessary functionality.
The area you enter editor data into is really an IFRAME, not a form
input. Javascript tools are used to copy the contents of the IFRAME
into the first input field in the form, when the form is submitted.
The first input field of the form must therefore be a hidden input
field to receive the contents of the editor. This input field should
be flagged as containing HTML (ie. the name of the field should be
fieldname#html) if you want to benefit from more advanced CMS features
such as embedded images and dyanmic content. This is automatically set
up for you, if you use make()
, but you may have to manually code it
on custom-built forms.
editor_javascript($section_id)
Returns the javascript that is needed to enable the HTML editor functions.
This is automatically invoked by input_htmleditor()
, but may have to be
manually inserted into custom forms to enable the editor. The $section_id
argument is required by certain dialogs (link, image) if you want to
automatically fetch pages and images to work with.