------------------------------------------------------------------------------
MC logo
CSc 231 Assignment 4
[^] PHP Programming Assignments
------------------------------------------------------------------------------

90 pts

A Barter Way

Due: Dec 10

This assignment is to create a prototype auction site like this one. As usual, you are free to copy the HTML generated by this program in building your own.

Features

Your program should have the features listed here. Feel free to run the example program to help figure out what I'm talking about. You are not required to use the same layout and screens as the example program, so long as you implement all the features in a reasonable way.
  1. Maintain a list of user accounts.
    1. Users may log on or log off, and many features are available only to users who are logged on.
    2. Each user has a login name and a human name. The login name must contain only letters and digits. The user logs in by entering the login name.
    3. Anyone may create an account. The creator must choose a login name and provide a human name. If the chosen login name contains illegal characters, or already exists, refuse to create the account and give reasonable feedback to the user.
    4. Optionally, you may implement account passwords. If so, allow the user to set a password when the account is created, and to change it later. Require a correct password for login. (Obviously, a serious system would have this feature. Since there's already enough to do here, I am not requiring passwords.)
  2. Maintain a list of items for bidding.
    1. Each item is an auction. It has an owner, a closing date, and a (possibly empty) collection of bids.
    2. Any logged-in user may add an item. Require the user to enter a description and closing date, and set the list of bids initially empty. As you may notice, the demo accepts entry of an auction length and computes the closing date from that.
    3. Any logged-in user may delete any of his own items; an item may be deleted only by its owner.
    4. Present a list of items currently available. For each one, show the owner, description, closing date, number of bids and high bid (if any).
  3. Maintain a list of bids for each item in the item list.
    1. Any logged-in user may bid on any item which has not closed.
    2. The bid must be an integer amount and must exceed the current high bid, if there is one.
    3. When a bid is submitted, you must check that it meets all requirements. If not, generate an appropriate message and do not record the bid.
    4. Each allowed bid creates a record containing the bidder, the amount of the bid, and the date and time the bid was submitted.
    5. Anyone may display the list of bids for any item. This listing shows the bidder, amount and date for each bid, in chronological order.
    6. An item's list of bids is deleted when the item is deleted.
  4. Any data entered by a user which is sent back in HTML, such as item descriptions, must be escaped so that it displays literally. This is both an appearance and a security issue.
  5. Be sure that your program cannot be broken or compromised by mal-formed input data. Generally, you will need to check that input is what it should be (integers are integers), or at least be sure the consequences of bad data are minor.

Hints and Advice

This section contains random hints and recommendations. In most cases, the demo is implemented this way. Nothing in this section is a requirement.

The demo implements all functions in a single file. Based on the data (or lack of it) in the $_REQUEST variable, it can tell an initial load from a form post, or figure out how to respond to the form post. This is actually more convenient that it might seem, since most operations do many of the same things. If you do use multiple scripts, make sure to put as much common code as possible in an include file.

As you can deduce from looking at the HTML, the primary variable which specifies the operation is called action, which is the name of most submit buttons. Some values of action are sent by multiple forms, in which case the variable source is used to tell them apart. Source is defined as a hidden field in several of the forms.

My script has these general phases:

  1. Process form submissions, such as log in, log out, item creation, new bids, etc. This section is a series of if tests to see if that's the kind of request we got, like:
    if (the user pushed the Sign In button from the login form) {
        check the user name and update appropriate variables.
    }
    else if(the user pressed the Add Item from the add item menu) {
        check the input and add the item to the list.
    }
    ...
    It's no error if none of these tests match; it might just not be that kind of invocation. If one does match and the operation fails, I assign an error message to a variable. This phase updates variables and the data recorded on disk, but does not generate any HTML.
  2. Generate the main menu form that appears at the top of the page. If the error message variable was set, it is output here.
  3. A series of ifs to generate a correct form, like this:
    if (the user pushed the Sign In button from the main menu) {
        generate the sign in form
    }
    else if(the user pressed the Add Item button from the main menu) {
        generate the new item form
    }
    ...
    else {
        generate the item list/bidding form.
    }

The data is collected on disk using the dba functions as demonstrated in the survey system and documented here. Choose a location in your own home area for the data file or files. I used three files, one for users, one for items, and one for bids. It would probably be just as simple to keep everything in a single file. Each file contains pairs of strings, so you must represent your data that way. I assign a unique identifier for each item when it is created using the uniqid function. This creates long ugly strings as identifiers, but users never need to deal with them. You can see them in the source code of the item listing. These are the key values in my item file. The data value associated with each key is a string built from the owner, number of bids, closing date and description concatenated together with commas between the items. Use the explode function to split out the parts when you read the file. Putting the description last lets me allow commas in the description by using the limit parameter on explode.

An alternative to uniqid is to keep a simple count. Create an entry in your item file with the key nextkey (or any name that doesn't conflict with others) whose value is the counter. To create a new identifier, increment nextkey and use its value.

My bids file contains a separate entry for each bid. The key is formed from the item identifier and the bid number separated by a colon. The associated data is the bidder, amount, and time separated by commas.

As you know from the first assignment, PHP uses a Unix timestamp to represent times. It's just a big integer. You probably want to use this to record times within your database. Use one of the provided conversions, such as strftime, whenever you need to present a time to the user.

As you will notice from viewing source, there's no rule that says you may have only one form in an HTML file. My item list actually has a form for every line of the table, and the main menu is a yet another form. Whatever is convenient.

When processing new bids, be careful to check that the auction has not closed. Even when you suppress generating a bid button for a closed auction, there's nothing to keep a user from submitting a bid from an out-of-date form. It is possible to create a form which will remove the bid button when the auction expires, if you use some Javascript or reloading tricks. It's fine if you do that, but you still need to check for expiration when you process a bid. There are a thousand reasons why your elegant trick may not work on some particular computer, either by some failure or a deliberate hack. The general rule is simple: Don't trust anything the browser tells you.

The requirements specify that user data placed on the page must be escaped to display literally. That means that if the data contains a <, you should send &lt; to the browser. The htmlspecialchars library function is good for this. One reason to do this is because a user might create an item description or something that contains < or > characters that damage your layout. A non-technical user who does this by accident will simply be annoyed that your nice web-based service is broken. A sophisticated user who does it on purpose deserves to know he's not smarter than you. But the most important reason is the possibility of a hacker inserting Javascript that will run in the browser of another bidding system user and transmit private data back to himself. This is known as a cross-site scripting attack.

My implementation uses a session to keep the name of currently-logged-on user. I keep both the login name and the human name there. The session identifier is passed by the default method through a cookie. All other data is passed through the forms.

Submission

Simply leave your page online on sandbox. Call it a4.php, and store it in a directory named csc231 under local_html under your own account on Sandbox. I'll run it and collect a copy of the source from there. Please leave the file in place at least until you receive a grade.