home—lects—hws
D2L—breeze (snow day)
hw06
Server side validation
Due: 2014.Apr.14 (Mon) 14:00.
We will incrementally improve on hw05—Client side validation's .W.o.W. page by
adding two features:
server-side validation,
and
making the form sticky.
As in previous homeworks, your page at
https://php.radford.edu/~yourUserId/itec325/hw06/index.php
should have a link to your skill-entry form near the top,
and include a list all your files (with links),
and should also display their source (between Apr.15 and May.31).
See hw04/hw04-soln for an example.
Sticky form
Modify your form so that it is sticky:
on validation error,
you are given back the form,
except that any information from $_POST is
pre-filled into the form (even if it wasn't valid).
For full credit, be sure to
have your drop-downs and your check-boxes sticky, too.
Since these were generated by a function,
this means modifying those functions so that they are passed in
an extra argument indicating what element(s) are to be pre-selected!
For checkboxes, this means passing in an array indicating what should be pre-selected;
you'll need to recall how your form handles the checkboxes,
so that you can make one or two test cases (honest, it'll save you time!),
so that you are then sure exactly what form of data your function has to work with!
Server-side validation
After submitting a form, the result should either:
- have the same "sucessfully submitted" as before,
if all the data successfully validates;
- or, list a message for each invalid piece of submitted data,
followed by the form itself again.
You should validate not just the things already validated client-side from
hw05 (including credit-card),
but also those things which aren't needed client-side:
the maximum-length on all text fields,
and that values from pull-down menus are valid.
I suggest your skill-form.php has the skeleton as
described in lect23-sticky—sticky forms:
// this is skill-form.php, a wrapper for info-form-helper.php and info-handle.php
//
if (isset($_POST['submitted'])) {
$errMsgs = validateAll(); // A function which checks all other input; returns array of error-messages.
}
if (!$errMsgs) {
require 'info-handle.php';
}
else {
echo "<h3>Form title</h3";
if ($_POST) then {
echo "Errors exist:";
print_r($errMsgs); // Well, let's print them nicer-looking than that. But you get the point.
}
require 'info-form-helper.php'; // Just like old info-form.php, except sticky, and submits to this new 'info-form.php'
}
?>
if (all form info is valid) {
require('skill-handle.php'); // same as before, on success
}
else {
print all the validation errors...
require('skill-form-body.php'); // the html for the form itself.
}
|
This will require pulling most of the form itself
into a separate file skill-form-helper.php, that gets included from here.
Once you do this, everything will be nice except that on your very first visit to
all your required fields will generate an error message.
Suggestion:
Write your php validation functions
so that they return an error-message (string) if validation fails,
and false if it succeeds.1
So maybe rather than call it validateSkillName($aSkillName),
you might call it skillNameErrMsg($aSkillName),
emphasizing that it is returning an error message (or, false).
Then, in our skeleton above,
the validateAll()
doesn't actually cause anything to print;
instead it returns an array of error messages (perhaps indexed by the name-attribute of the
offending input?).
This array can (a) is used to detect whether or not errors exist,
and (b) saves the repeated-code of having an echo statement
alongside each validation call; you can just loop over the array.2.
You must have test cases for your validation functions
(about 40% of overall grade) —
test your skillNameErrMsg,
attributeErrMsg, etc..
For functions returning false-or-error-string, it's acceptable to just
test whether the result is false
(w/o worrying about the exact error-message contents).
If you were careful to write functions which took all their input as parameters
(and didn't look things up in $_POST themselves),
and returned (w/o printing),
then testing is the same as ever.
But if you wrote any of your functions so that they
need to access $_POST internally, you can either
-
modify the functions to accept an array as another parameter
(passing $_POST when calling from your actual form,
but passing arrays filled with test-data when calling from your test suite).
-
Or, have a test-file that
defines an array that just-so-happens to be named $_POST,
and then call your validation functions.
This is more cumbersome, because for each test case you'll need to modify
the contents of $_POST.
Note that some validation functions might be fairly specific to this function
(e.g. skillDescrErrMsg($_POST['skillDescr']));
others might be more generic/re-usable:
(like numInRangeErrMsg($_POST['minLevel'],30,100,'minimum skill level')3).
A possibly-helpful hint:
The function getPost
from hw04-soln
is a way to get values out of $_POST (to pass to your function),
w/o triggering a warning if that field had been left empty
(and hence the index doesn't even exist inside $_POST).
When checking that the drop-downs (or, check-boxes) are valid,
do not use a six-way if-else-if;
use in_array,
along with the constant-arrays in hw04/hw04-soln/#skill-constants.php
(the exact same arrays you used to generate the drop-downs/checkboxes
in the first place).
Other requirements
These apply to all homeworks for this class:
-
Each file start should start with
with a PHP or HTML comment with your name, class, etc.
(after a doctype declaration and perhaps <html>).
-
Use meaningful variable names, function names, and good comments as needed.
-
Write functions (both php and javascript) as appropriate, to avoid repeated work.
Include test cases for all non-void functions.
The number of test cases depends on the particular function;
include enough to capture different sorts of answers.
(For example,
pluralize deserves at least three tests: the numbers 0, 1, and more-than-one;
blend deserves at least four tests:
each of the two input strings could be odd or even, and that affected the splitting-point;
wanted strings of even-length and odd-length;
a function to create a drop-down html menu might be fine with
just one test case (an array with several items) if you are confident
that an empty-array or array-with-one-element is not really
any different behavior.)
Remember,
writing test-cases first often clarifies exactly what your code needs to return.
-
Use standard XHTML tags and make sure any javascript does not use browser-specific constructs.
-
All code/html should be well formatted with appropriate
white space and indentation so it is easy to read.
-
Strive to minimize lines of code longer that 100 characters.
-
If you have any questions, use the discussion board.
-
Do not modify your final submission after the due-date;
if you want to make changes, copy all your files to a new directory and work on those.
1
A first impulse is to have a function which returns true if the field is valid,
and false otherwise.
But you'd still need a separate function which generates informative specific error messages.
To avoid repeated code, you'd end up having your T/F validation function just
call the error-message version and check for that result being false/empty-string.
At that point, you might as well just have functions that return
error messages (or false),
and the wrapper
function fieldXValid() { return (inputXErrMsg() == ""); }
is arguably a bit superfluous.
↩
2
You can even (c) still have the error messages around as you are later
re-printing the (possibly sticky) form,
so that you can, server-side, generate error messages that are right next to the
offending input tag.
However, this is unnecessary given our fancy javascript error-displaying from hw04.
But it would make sense when your server-side validation is
checking things unavailable to the client-side validation
(e.g. “this item out of stock” or “this credit card was denied”).
↩
3
A moment of thought reminds us that if our function is generic but still wants
to give specific, helpful error messages, then we might want to pass it the
field-name's English description, solely for the purpose of constructing an error message,
even though it's not needed just to check validity per se.
↩
home—lects—hws
D2L—breeze (snow day)