This assignment asks you to use HTML forms, PHP, and regular expressions. You will write the following pages:
Online dating has become mainstream with popular sites such as eHarmony, match.com, OkCupid, and Plenty of Fish. Your task for this assignment is to write the HTML and PHP code for a fictional online dating web site for extremely desperate single nerds, called NerdLuv.com. The site will consist of two pages: a front page called nerdluv.php
(mostly provided to you) that contains a form for a user to submit information, and a result page called results.php
(that you will write entirely) that displays single people who match well with the applicant.
CSE non-majors do not need to submit any .js
file, since by default this assignment needs no client-side scripting. Turn in the following files:
nerdluv.php
, the HTML code for the front signup page (mostly-complete version provided)nerdluv.css
, the CSS styles for both pages (complete version provided)results.php
, the PHP code for the results page (no starter code provided; write this yourself!)nerdluv.js
(optional), the JS code for the signup page (required for CSE majors only)Part of your grade comes from uploading your files to Webster at the following URL. Please do not place a solution to this assignment online on a publicly accessible (un-passworded) web site.
nerdluv.php
):A default appearance has been provided for you in the skeleton HTML and CSS files, but you may customize it in any way you like, so long as the functionality described in this document still works as specified.
The
nerdluv.php
page begins with the NerdLuv logo image, nerdluv.png
. The text where meek geeks meet
appears under the image. 2em below this text are two HTML forms. The first form is the "Returning User" form, which allows a user who has already joined the site to view his/her latest matches. The second, larger form is the "New User Signup" form, which allows a user to join the dating site.
Each overall set of form fields is 30em wide, centered within the overall page, and has a background color of #E0E0FF
and a 1px black border. Each field set's label has a white background and a 1px black border. The default font for all text on the page is 12pt in Century Gothic, Arial, or any sans-serif font available on the system. 1em of vertical spacing separates adjacent controls on the form.
The "Returning User" form contains the following elements:
results.php
. This button has a background color of #FFAAAA
, and its text is bold and 1.5 times as large as normal text on the page.
The "New User Signup" form contains the following elements:
results.php
for processing. This button has a background color of #FFAAAA
, and its text is bold and 1.5 times as large as normal text on the page.
results.php
):
The results.php
receives input from nerdluv.php
and outputs HTML. The page operates in two modes:
nerdluv.php
page. In this mode, results.php
expects just a single query parameter representing an existing user's name. It uses this name to look up the other information about that user in its data file, then shows all other users that match that person. It's okay for your code to be case-sensitive; that is, if the user types "bill GATES", your code doesn't have to be able to tell that this is the same person as the "Bill Gates" in the file. But if you want to handle this issue, you may.
For all GET requests, you may assume that the user name submitted will be present in the data file. In other words, you don't have to handle the case where a user might try to View Matches who hasn't signed up before.
nerdluv.php
page. In this mode, results.php
expects many query parameters representing the various data from nerdluv.php
's form, such as the applicant's gender, favorite operating system, and so on. (The exact names and values of those parameters are your decision.) The page should save the applicant's data to its data file (described later) and then display any other users that match the applicant.
Except as specified in the "Data and Validation" section, you may assume that the form data submitted by the user is completely valid and will not cause any problems for your code. You may also assume that no user will submit data for a user name that is already in the system.
You can test whether a given request to it is a GET or POST with the following PHP code:
if ($_SERVER["REQUEST_METHOD"] == "POST") { # a POST request } else { # a GET request }
In either mode, the page begins with the same
nerdluv.png
banner image and slogan as the nerdluv.php
. (If you want to remove the redundant HTML content between the nerdluv and results pages, you may want to read about the PHP include
function.)
2em below the banner slogan should be a level 1 heading saying "Matches for APPLICANT NAME" where APPLICANT NAME is the name of the person who just submitted the form. Below this is a list of singles that "match" the applicant. A "match" is a person in the dataset who has a "strength of match" score of at least 6 points when compared to the current user. Strength of match points are earned for the following qualities:
You have probably noticed that these "strength of match" rules can lead to results outside the applicant's specified preferred gender and/or age range. For example, if you are a man seeking women but have a lot in common with a man in the dataset, NerdLuv will show his data anyway. This is a little odd, but let's face it, if you are using this dating site in the first place, you should probably keep all your options open.
Each matching single should have have his/her name displayed on a line 30em wide, centered within the page, with a background color of #E0E0FF
. 1em below this is an image of the single, shown with a width of 150px. 1em to the right of this image is text about the single, including age, what he/she is seeking, the personality type, OS, and strength of match. There is 3em of space below the image for each match.
Underneath all the matches, the results page shows a paragraph with the total number of matches found. It is possible for this number to be 0 if no singles match the applicant.
Both pages have a title of NerdLuv.com
. Both pages have a "favorites icon" of heart.gif
. At the bottom right of both pages is the standard pair of W3C validator buttons.
Screenshots in this document are from Windows XP in Firefox 2.0, which may differ from your system.
Your results.php
page reads its data about singles from a file named singles.txt
, which is placed in the same folder as the script itself. This file contains data records in exactly the following format, where each line contains the user's name, gender (M or F), age, Keirsey type, favorite operating system, seeking gender(s) (M, F, or MF), minimum seeking age, and maximum seeking age, separated by commas:
Ada Lovelace,F,96,ISTJ,Linux,M,59,99 Donald Knuth,M,70,INTJ,other,MF,12,17 Marty Stepp,M,28,ISTJ,Windows,F,18,39
Each time the script is run, it should read this file's contents to find the singles that match the applicant based on the above criteria. If results.php
is contacted as a GET request, then the file is only read and not modified. If results.php
is contacted as a POST request, the file is read, the new user's information is added, and the new information is written to the file. You can add the new user's information to the end of the file and do not have to maintain any particular order to the singles in the file. Recall that you can break apart strings and put them back together using the PHP's explode
and implode
functions.
When you initially upload your files to Webster, you will need to change the file permissions on singles.txt
so that PHP is able to write changes to this file. In your SSH Tectia window, right-click singles.txt
in the right-side pane and choose Properties. In the Properties window, enable Group Write permission by checking the box shown in the screenshot below.
The image for each single is stored in a file in the images
subfolder relative to the PHP script. The image for a single is a file with the .jpg
extension whose name is equal to the person's name in lowercase with all non-alphabetic characters converted into underscores. For example, the image for Bill Gates is stored in bill_gates.jpg
, and the image for Rosie O'Donnell is stored in rosie_o_donnell.jpg
. You can replace characters in a string using the preg_replace
function and regular expressions, to help you map from a given user's name to his/her image filename. File names are case-sensitive, so you may want to use functions such as strtoupper
or strtolower
.
A default set of user data and image files will be provided on the course web site. Some users may not have images; in particular, any user who submits new data into the app will not have an image (unless you choose to add that feature, described in the CSE Majors section). To deal with such cases, your results.php
code should test whether each user's image exists (using PHP's file_exists
function), and if it doesn't, you should instead display the image default_user.jpg
.
Your page should also perform a minimal amount of validation on the data that is submitted. In either a GET or POST request, if the name submitted is blank, the results.php
page should show an error message rather than attempting to show the user's matches. Similarly, in a POST request, if the Keirsey personality type is not valid, the results.php
page should show an error message and should not save any data or display any matches. A valid Keirsey type is a string of exactly 4 characters, where the first character is either I or E, the second character is S or N, the third character is T or F, and the fourth character is J or P. For full credit, you must validate the Keirsey type using a single regular expression and call to the preg_match
function.
CSE majors must complete the following additional features:
results.php
that tests all query parameters received for validity. Use regular expressions to do this as appropriate. Specifically:
"robot"
are allowed.)If some of the form data is invalid, instead of showing matches, the response page should contain an error message displaying what was wrong. For example, if neither "seeking" box is checked, suitable messages would be, "Error: Invalid submission data." or, "Error: You forgot to submit a value for seeking." No data should be saved if the submission is invalid, and no matches should be shown.
nerdluv.php
page in a file nerdluv.js
. This code should arrange it so that whenever the form is about to be submitted, the following checks are performed:
Your code can intercept the form as it's about to be submitted by handling the form's onsubmit
event. You can test whether a JavaScript string matches a given regular expression by calling its match
method. If any form data is invalid, cancel the form submission using Prototype's Event.stop
method, and show an error message to the user. If you like, you can also validate other input fields on the page, and/or highlight any invalid input field(s) with a background color so that the user sees the error.
nerdluv.php
page so that it allows the applicant to submit a photo. To handle uploading of photos, add a file input box to the nerdluv.php
page that allows the user to browse for a file to upload as a photo. (A screenshot is provided on the course web site.) When the results.php
script receives a POST request, it will save this photo in the images
subfolder with the others using the file naming system described previously (the user's name with spaces replaced by underscores, such as dick_cheney.jpg
) and show it when subsequent users search for matches.
Regardless of how many additions you choose to implement, the main program behavior and appearance described previously should still work as specified. If you have a different idea for a creative addition to this program, please ask us and we may approve it for credit as a substitution for one of the above. Non-CSE-majors may choose to implement the above features if so desired, but it will be ignored for grading purposes so long as it does not break any other functionality.
We suggest the following development strategy for this assignment:
nerdluv.php
code to use forms.results.php
that works for returning users.results.php
to work for new user signup, writing the new user's information to the file in the proper format and then displaying the same information you did previously.
Before working on the results PHP code, get the initial nerdluv.php
behaving properly. You will have to modify the provided nerdluv.php
file to add the proper forms and query parameter names to it. Remember that controls whose values are to be submitted as form query parameters must have suitable name
attributes. For example, if you want an input text box to submit its text as a query parameter named "creditcard", you'd say something like:
<input type="text" name="creditcard" size="16" />
Also remember that sometimes you must add a value
attribute to a form control to affect the way it is submitted (for example, when dealing with radio buttons, and possibly select and check boxes).
You can test your form to see that it is submitting the proper parameters by temporarily setting its action
attribute to:
https://webster.cs.washington.edu/params.php
When you're working on your results.php
code, we suggest that you implement the "Returning User" (GET) code first, before working on the new user signup (POST). This will require you to look up the returning user's information in the input file. Write the code to look up this information and print it. Then you'll need to compute the strength of match with this user compared to every other user. Do this in a separate pass over the file.
You can test the GET code by typing in names of users already in the system, such as Ada Lovelace or Marty Stepp. We suggest that you use temporary print
statements to display which aspects of the user lead to strength of match points. For example, if the operating systems match, print a message along with the strength of match computed so far. This will help you debug problems with the scores. Also consider using the print_r
function to print the contents of arrays for debugging, such as $_REQUEST
. If things don't look the way you expect, you may want to View Source of the page to see what HTML code has been printed.
Be wary of redundancy in results.php
. Try to combine as much of the GET and POST cases' code as possible. All actions related to GET vs. POST (saving the new user's data, or looking up the existing data from the file) can be handled at the start of the code, and then everything else between the two cases (looking through all singles and displaying matches) is the same after that. We suggest that you extract the query values from the $_REQUEST
array into variables such as $name
, $age
, and $operating_system
so that you can use these same values whether it's a POST (in which case their values come from $_REQUEST
) or a GET (in which case their values come from parts of a line in the input file).
Submit your assignment online from the turnin area of the course web site. For reference, our results.php file has roughly 100-140 lines of PHP, but you do not need to match this total.
Your HTML and CSS code should be W3C valid and have comment headers. (The HTML is generated by PHP in this case. You don't put your PHP source code into the validator, but rather the HTML output that it generates.) Your CSS code should avoid redundancy as much as possible. Stylistic information should be placed into CSS and not into HTML/JS.
Your PHP and JavaScript (if any) code should follow reasonable stylistic guidelines similar to those you would follow on a CSE 14x programming assignment. Minimize redundant code, decompose the problem into functions intelligently, minimize the number of global variables, utilize parameters and return values properly, correctly use indentation and spacing, avoid long lines over 100 characters in length, and place a comment header at the top of your code files and atop every function explaining that function's behavior. You should only use material that has been discussed during the first eight weeks of the course, unless given explicit permission from the instructor.
Your JavaScript code (if any) should follow similar style guidelines to those just stated for PHP, should also pass the JSLint validator, and should correctly utilize XHTML DOM objects for manipulating the page contents.
Your PHP code should generate no error or warning messages when run using reasonable sets of parameters. The source code that is output by your PHP pages will be graded by the same criteria as normal HTML code, meaning that it should be valid XHTML, should be properly formatted and indented, and so on. Your PHP code should use the "embedded PHP" style shown in class, and for full credit, it should not contain any print
or echo
statements. Produce all output by writing pure HTML in "HTML mode", and insert variables' values using PHP expression blocks.