RU beehive logo ITEC dept promo banner
ITEC 325
2019fall
ibarland

Server-side validation

Due Oct.04 (Fri) in classby 17:00 for extra 10% of earned-points, or Sat 23:59 otherwise. Submit files on D2L, and have them online at php.radford.edu/~yourUserName/itec325/hw05/index.php. (No hardcopy needed.)

I strongly recommend completing at least the following portions by Oct.03 (Wed)


We will incrementally improve on hw03’s Okaymon page by adding server-side validation.
You may use parts/all of the hw03-soln (now available, Sep.28 (Sat) 22:22)(will be available Sep.29 (Sun) midday) and/or lecture example, as long as you cite it of course.

You should have a page https://php.radford.edu/~yourUserId/itec325/hw05/index.php which contains links1 to: (i) this homework page, (ii) your okaymon-form.php, and (iii) your okaymon-handle-test-i.php files. Be sure to use the filenames specified here. Presumably, you will want to start by copying your hw03/ directory to a new hw05/ (via cp -r ).

What to validate

The following properties should hold (and you should report a validation-error-message if they don't):

  1. The trainer's name is required and must contain at least one letter-character (not just digits/punctuation etc.), is at least 5 characters long, and no more than 50 characters long.
  2. The species is required and must contain at least one letter-character (not just digits/punctuation etc.), and no more than 25 characters long2.
  3. The flavor-text is optional, but (if present) should be no more than 200 characters long.
  4. The weight must be a non-negative number less than 10,000 (required).
  5. All information from pull-down lists must be valid options (energy-types, weight-units) (required).
  6. All information in radio-buttons must be valid options (required).
  7. The Intellectual-Property waiver checkbox is required.
  8. (bonus) In validating the above properties, first trim any leading/trailing whitespace from the user’s input. (You don't need to trim from values in pulldowns/checkboxes.)
    warning: Only call trim on strings — not any sub-arrays inside $_POST! The function is_string can help.

code structure

  1. (4pts) As before, after submitting okaymon-form.php will lead to a page which prints the received information. However, the page's title (and, its headline) should be either something like “okaymon info submitted” (as before) or something like “okaymon form contained n errors”. Then, if there were errors, give a list of the error-messages before printing the received-information. Error message should be specific: e.g. rather than saying a field is “field-name is either required or too long”, report “field-name is required”, or report “field-name is too long”.

  2. (30pts for validation, including appropriate helper functions and their tests)
    Have a separate file okaymon-validate.php that contains validation-functions specific to this form. Include a top-level function allErrorMessages which takes in an array containing what $_POST might contain, and return an array of 0 or more error-messages. For each of the form’s inputs, have either:

    Each reported validation-error message should start with the name of the field containing the error (probably name attribute itself, so long as that name is human-understandable).

  3. (3pts) Include an additional file “okaymon-constants.php” which simply defines things needed by both the form-generation and the form-validation: the list of categories, the maximum weight, the max-length of all pertinent fields3, etc..
    PHP tip: PHP, unlike most languages, has an …odd notion of “global variable”. Even if a function is defined in a context which had access to a variable, in order to use that variable inside the function you have to either look up its name inside the array $GLOBALS, or declare your intent by (re)declaring the variable as global inside your function.
    require_once("my-constants.php");  // defines variables `$foo` and `$bar`.
    echo $foo;
    function stuff() { 
        echo $GLOBALS['foo'];
        // OR
        global $bar;
        echo $bar;
        }
          
  4. (4pts) Include an external CSS file. Include at least two named styles; think up appropriate names4 for them:

Include unit-tests for each function you write, of course. Also, add at least two more “okaymon-handle-test-N.php” pages: one which has only a single invalid input, and one which has all inputs invalid (including the weight-units and energy-type). Keep in mind that if an input-field has multiple ways to be invalid, you should be confident your form-handler-tests catches the error — e.g. one where species which exceeds the max-length, and another where it has no letter-character.

You might want to start by creating another sample-page which includes some of the wacky things to check for: an entry which is nothing but spaces; an entry claiming the that the dropdown-item “easy-peasey-lemon-squeezy” was selected (even though your dropdown has no such option), etc.. This will help focus your thoughts about what you need to check, when validating.

Any generic validation functions (which could be re-used directly for other projects) can be put into your utils.php. …Although, that name “utils” is starting to get a bit abused, since these aren't so much general-purpose utility functions, as part of a suite of validation functions. (You are encouraged, but not required, to put such generic validation functions into a separate file yet. The rule-of-thumb would be: Might this be code you'd want to repeat when validating an entirely different web-form (like your project)? No matter how you organize your code, each file of functions should have its own associated -test file.)

For example, for validating the weight, have a generic function that compares an input-string against any two numbers. In order to be able to return a helpful error message, that function might also take in the field's name, perhaps numInRangeErrMsg($inputs['weight'],50,100,'weight')

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). For testing allErrorMessages, it's acceptable just to check whether the array it returns has the intended number of items: test( count(allErrorMessages( array()), 3 );. Be sure to test for each of the validation-tasks listed above! You might keep your test-arrays aligned with the same arrays used in your sample-i files.

hint: When grading, some of the automated things I'll check: one file has includes “constant” in it’s name; two files have the word “constant….php” inside them; the word “puddle” only occurs once; one file ends in “.css”.
    # csh shell commands.  
    # You can just copy/paste the bits inside the back-ticks into the shell, and compare to the target answer.
    set numConstFile =  `ls * | grep onst | wc -l`
    set numConstFileTarget = 1
    set numFilesMentionConst = `grep --files-with-matches -- -constant * | wc -l`
    set numFilesMentionConstTarget = 2
    set numFilesMentionPuddle = `grep --files-with-matches puddle * | grep -v -- -test | grep -v -- -handle | grep -v -- -sample | w
c -l`
    set numFilesMentionPuddleTarget = 1
    set numPuddles =  `grep puddle * | grep -v -- -handle | grep -v -- -test | grep -v -- -sample | wc -l`
    set numPuddlesTarget = 1
    set numCSSFiles =  `ls * | grep .css\$ | wc -l`
    set numCSSFilesTarget = 1
  

Other requirements

These apply to all homeworks for this class:

1 For fun, you're urged to automate the creation of a page that just has links to a bunch of other pages (many in the same directory).

Some helpful functions for this task might include hyperlink, array_map, and a function to create an unordered list (as written in a lecture). scandir might also be helpful. You can even look at a function for a similar task, but only if you understand how it works, and rewrite it to only do the things pertinent for your task.

     
2 The species-name may have to appear on the top of a playing-card, so we limit its length rather strictly.      
3 I recommend an array of max-lengths, which map the name-attribute to the length: array( 'trainerName' => 80, ).      
4 Remember that a good CSS style-name describes the meaning (semantics) of the style, not the particular styling it creates: something like “menu-item” or “telephone-number”, or “default-entry”, and not “centered” or “bold-sans-serif” or “blue-italics”. (w3.org's Tips for Webmasters agrees; here is some further discussion.)      

logo for creative commons by-attribution license
This page licensed CC-BY 4.0 Ian Barland
Page last generated
Please mail any suggestions
(incl. typos, broken links)
to ibarlandradford.edu
Rendered by Racket.