Recent Question/Assignment

Practical 3
This practical is worth 10% of your topic grade and is divided into 5 checkpoints (worth 2% each).
The purpose of the checkpoints is to provide you with the skills necessary to complete the practical component of the web development assignment, which constitutes a significant portion of your marks for this topic. Please seek assistance from your tutors on any aspect of the tasks that you do not understand.
Whilst you are encouraged to discuss the concepts covered in this topic with your fellow students, please bear in mind that all work you produce and submit must be your own and that submissions will be subject to similarity checks. As a student, you should ensure you are familiar with the University’s Academic Integrity Policy and the penalties that can result from academic dishonesty and plagiarism. To that end, you may be asked (at any time) to explain your checkpoint solutions and the process you went through to develop them.
Submission and assessment
To submit your checkpoints for marking, upload a zip file of your practical directory (including all subdirectories) to the Practical 3 submission box on FLO by 11pm Friday in week 10. Ensure your zip file contains all of the source PHP, CSS, and JavaScript files for each of the checkpoint tasks. Your tutor will download your submission and mark it according to the specifications outlined in this handout. Your mark will then be uploaded to FLO.
Before you begin…
In order to develop PHP webpages, you will first need to download and install the AMPPs package. AMPPs provides a pre-configured web development stack that incorporates the Apache web server, MySQL DBMS, and PHP interpreter as well as the phpMyAdmin management interface for MySQL. Together, these components support back-end development.
Visit the resources section on FLO and click on the AMPPs package link for your platform. Once downloaded, install the package as you would any other application.
The Module 5 workshop videos cover an introduction to the AMPPs package.
Once AMPPs is installed, start Apache and MySQL and navigate to http://localhost/phpmyadmin to verify the installation.
Flinders University / College of Science and Engineering
Checkpoint 1
For this practical, you will build a simple task list ‘web app’ using PHP.
1. Similar to the previous practical, you should first establish a directory (folder) structure for the files you will be working on in the following checkpoints. Begin by creating a directory for Practical 3 somewhere on your machine.
2. Download from FLO and extract the contents into your Practical 3 directory. You should now have a directory structure that looks like the following:
3. Open the checkpoint-1 directory in VS Code. Open the db.sql file and copy the contents. The file contains the SQL statements necessary to create the database you will be working with for the rest of the practical.
Switch to the browser window/tab where you have phpMyAdmin open and click on the SQL tab at the top. Paste the contents of your clipboard (the SQL) into the textbox and click Go in the bottom right corner (below the textbox). You should receive a series of status messages with green ticks indicating the successful execution of the statements.
4. Switch back to VS Code. The index.php file contains the template of a tasks page that you will complete by adding the necessary PHP code so that it retrieves the current list of tasks from the database when loaded. If you inspect the contents of the file, you will note the existence of PHP opening ( ?php) and closing (? ) tags that denote the block where PHP can be written. The require-once statement includes the contents of another PHP file,, that will establish a connection to the database, so you should not delete it (you are encouraged to inspect it, though).
5. Within the PHP tags, below the require-once, create a variable called sql and assign it the following query string:
-SELECT id, name FROM Task WHERE completed=0;-
6. PHP includes native support for accessing various DBMSs. For this practical, you will use the procedural MySQLi interface to interact with the MySQL database and create/read/update records.
The mysqli_query function is used to submit a query to the database and retrieve the results. The function returns a result set on successful execution or a false value on failure, which makes it suitable for using within an if statement to ensure that result parsing only occurs when there are results available.
Declare an if statement using the following as the condition:
$result = mysqli_query($conn, $sql)
The $result variable will store the result set on success and will be available within the if statement for parsing. The $conn variable is declared within and holds a connection to the database, and the $sql variable is as defined previously.
7. Within the if statement, declare another if statement and use the mysqli_num_rows function to check that the number of rows returned by the query is at least 1. The mysqli_num_rows function takes a result object as a parameter, which you have available as $results, and returns the number of rows.
8. You are now ready to parse the results and generate the HTML necessary to display them on the page. You can access each of the rows by using the mysqli_fetch_assoc function, which will return an associative array for the next result row or NULL if there are no more rows. As with the mysqli_num_rows function, mysqli_fetch_assoc takes a result object as its parameter.
Because there is likely to be more than one row of data, you will want to use a loop to iterate over each row. Within the if statement defined in step 7, declare a while loop using the mysqli_fetch_assoc function as the condition. The loop will cease when all rows in the result set have been iterated over.
while ($row = mysqli_fetch_assoc($result) { ... }
Within the loop, use one or more echo statements to output the name of each task. You can access the task name via the row key name; i.e., $row[-name-]. The tasks should be output as an unordered list, so you will need to surround the while loop with echo statements for the list tags and then incorporate the list item tags into your output of each task name within the loop — an example of this is as follows (shown in pseudo code):
echo opening list tag
while ($row = mysqli_fetch_assoc($result)) { echo the task name within list item tags
} echo closing list tag
It is good practice to free up resources after they are finished with, so call mysqli_free_result after the loop: mysqli_free_result($result);
9. Finally, close the connection to the database by calling the mysqli_close function as follows after the outer if statement you defined in step 6. The function takes in a reference to the current connection. mysqli_close($conn);
Navigate to index.php in a browser — remember, the page is hosted on a local web server instance, so the URL will be something like http://localhost/practical/checkpoint-1/index.php — and verify that you see a list of tasks.

——————————————————— End of Checkpoint 1 ———————————————————
Flinders University / College of Science and Engineering
Checkpoint 2
This checkpoint will involve adding a menu to your page and styling it with CSS.
1. Make a copy of your checkpoint-1 directory and name it checkpoint-2.
2. Open the checkpoint-2 directory in VS Code.
3. Uncomment the following two lines in your index.php page
!-- ?php require_once -inc/; ? --
!-- script src=-scripts/script.js- defer /script --
The first includes the contents of a menu file that is provided for you within the inc directory. The menu is composed of an unordered list of menu items (anchor elements). You will create the second and third pages in later checkpoints. Take note of the id attribute defined for the list, which you can use when styling it.
The second line references a script that has also been provided for you in the scripts directory. This script contains a JavaScript function that will apply a class called selected to the anchor element in the menu that corresponds to the current page. It does this by inspecting the current URL, via document.location, and checking for a match against each anchor element’s href attribute. As before, you can use the class when styling the menu.
4. Within the styles subdirectory, create a new file called style.css. All CSS you create must be defined in this file. There should be no internal (via style tags) or inline (via a style attribute) CSS used.
5. Add a link element in index.php that refers to the styles/style.css file.
6. Edit index.php and style.css to produce a page that looks similar to the image below.
Note that minor differences are fine as long as your page is a close replica.
Key style details:
• The margin for the entire page is 15px on all sides.
• The body font is Helvetica (fallback to Arial then sans-serif) and 14px in size.
• The heading font size is 16px and the font weight is bold. The heading also has a bottom margin of 10px.
• The paragraph/list item line height for each task in the list is 1.5em.
• Menu: o Each menu item has a right margin of 15px, a colour of black, and floats to the left of its container.
o When hovered over, menu items change colour to #1565c0. o A selected menu item has a colour of #1565c0 and a font weight of bold. o The menu border is a solid 1px line in the colour #ddd (bottom only).
o The menu has a bottom padding of 10px. o The menu has a bottom margin of 30px.
——————————————————— End of Checkpoint 2 —————————————————
Checkpoint 3
This checkpoint will involve creating a new PHP page to add tasks.
1. Make a copy of your checkpoint-2 directory and name it checkpoint-3.
2. Open your checkpoint-3 directory in VS Code. Create two new files in the root of the checkpoint-3 directory called add.php and add-task.php.
3. Edit add.php and styles/style.css to produce a page that looks like the image below. The provided HTML can be used as a starting point. Note that minor differences are fine as long as your page is a close replica.
• All input elements should have… o a display property of block;
o a 1px solid border in the colour #babdbe;
o a left/right padding of 6px and a top/bottom padding of 3px; o a bottom margin of 10px.
• The text input element has a width of 300px and should also define the required attribute;
• The submit button text changes colour to #1565C0 when hovered over.
4. Ensure your text input element has a name attribute as you will need to reference this when retrieving its value. In your form element, define the method and action attributes accordingly:
• Assign the action attribute a value of add-task.php.
• Assign the method attribute a value of POST.
5. Within add-task.php, add PHP code to process the submitted form and insert a new record into the database.
This file will process the form only, so it does not need any HTML and can therefore be a pure PHP file. At the top of the file, declare the PHP opening tag. As the form is submitted using the POST method rather than the GET method, the task name value will not be appended to the URL as a query string. Instead, the value will be stored in the body of the HTTP request. You can access the value via PHP’s ‘superglobal’ $_POST variable, which is an associative array of the current POST data. Key values in this array correspond to input element name attribute values.
You can verify that a value is available for a given key by using PHP’s isset function, and it is generally considered good practice to do so (using an if statement) before attempting to use it; e.g.,
if (isset($_POST[-task-name-])) { ... } // This assumes the input element is named 'task-name'
The next step is to include the file to open a connection to the database. This can be achieved in the same way as in index.php; i.e., require_once -inc/;
Next, you will prepare the SQL statement. Declare a variable called sql and assign it the following SQL string:
-INSERT INTO Task(name) VALUES(?);-
The ? is a placeholder for the task name that will be extracted from the $_POST array. Declare another variable called statement and assign it the value returned by the function call mysqli_stmt_init($conn). This function will initialise a new SQL statement using the established database connection stored in $conn. Add the following calls to mysqli_stmt_prepare and mysqli_stmt_bind_param below to prepare the statement and bind the task name to the ? placeholder (change task-name to whatever you named your input element).
mysqli_stmt_prepare($statement, $sql);
mysqli_stmt_bind_param($statement, 's', htmlspecialchars($_POST[-task-name-])); // The 's' in mysqli_stmt_bind_param indicates a string parameter
The statement is now ready to execute. You may be wondering why the POST value was not simply concatenated to the SQL string above. Whilst this would work, it is open to SQL injection attacks as the value entered by the user could contain malicious SQL. Preparing a statement in the manner described protects against this as the DBMS is sent the statement structure before any user provided parameter values are inserted into it. The htmlspecialcharacters function wrapping $_POST[-task-name-] is a PHP function that provides similar protections by replacing special HTML characters to prevent unwanted HTML from being inserted — this is a form of input sanitisation. PHP’s filter_var function provides many more options for performing input sanitisation of form fields.
To execute the statement, pass it to the mysqli_stmt_execute function. This function returns a boolean that indicates whether the statement was executed successfully or not (i.e., if the task was successfully inserted into the database). If the return value is true, use the header function to redirect the user back to index.php. If the return value is false, you can output the error that occurred by echoing the value returned by a call to mysqli_error($conn). header(-location: index.php-);
Finally, as you did previously in step 9 of Checkpoint 1, close the connection to the database.
6. Verify that you can enter a new task into the add task page and that it appears at the bottom of the task list.
——————————————————— End of Checkpoint 3 ———————————————————

Checkpoint 4
This checkpoint will involve adding functionality to support completing tasks.
1. Make a copy of your checkpoint-3 directory and name it checkpoint-4.
2. Open your checkpoint-4 directory in VS Code. Edit your index.php file and modify the output of each task name (as completed in step 8 of Checkpoint 1) as follows:
• Embed the task name within an HTML anchor element.
• Set the href attribute of the anchor element to complete.php?id=XX where XX is the task’s id. You can get the task id value using the row key id; i.e., $row[-id-].
3. Modify your styles/style.css to style the task anchor elements as follows:
• The task name (now a link) should still appear in black and with no underline.
• When hovered over, the task name should change colour to #1565c0 and apply a line-through decoration
4. Create a new document called complete.php in the root of the checkpoint-4 directory. Edit this page so that it reads the id value from the URL query string (accessible in PHP using the $_GET array, which work similarly to $_POST) and then updates the associated task record in the database to mark the task as completed.
As with the add_task.php page, complete.php does not need to display any HTML and can therefore also be a pure PHP page. The PHP code required to update the database is essentially the same as the previous checkpoint. However, as noted above, you will need to use $_GET to retrieve the id value instead of $_POST (do not forget to modify the mysqli_stmt_bind_param function) and your sql variable value will need to change to the following:
-UPDATE Task SET completed=1, updated=now() WHERE id=?;- Remember to close the database connection.
5. Verify that clicking a task in the task list causes it to disappear off the task list. You may also wish to revisit phpMyAdmin and view the Task table to check that the task you selected has been updated in the database with a completed value of 1. Finally, if you have not already done so, mark the Checkpoint 1 to 4 tasks complete on your list.
——————————————————— End of Checkpoint 4 ——————————————————— Checkpoint 5
The final checkpoint will involve adding a new PHP page to display a history of completed tasks.
1. Make a copy of your checkpoint-4 directory and name it checkpoint-5.
2. Open your checkpoint-5 directory in VS Code. Create a new file called history.php in the root of the checkpoint-5
directory. Edit the page so that it displays a list of completed tasks, which can be retrieved from the database by using the following SQL query:
-SELECT name FROM Task WHERE completed=1 ORDER BY updated DESC;-
You may wish to refer to your index.php page as a template/reference. Note that completed tasks are not expected to be clickable (i.e., anchor elements/links).
3. Modify your styles/style.css file accordingly so that the page looks like the image below. Each completed task should appear in the colour #9e9e9e with a line-through decoration.
Note that minor differences are fine as long as your page is a close replica.
4. Finally, complete the Checkpoint 5 task and verify that it appears at the top of the history.php page.
——————————————————— End of Checkpoint 5 ——————————————————— Extension
Note that this is an optional extension exercise and is not a checkpoint. It does not contribute any marks.
Extend your index.php page so that it displays the number of tasks as illustrated in the images below. The formatting should display the correct grammar for singular and plural task counts (e.g., 1 task or 2 tasks). If there are no tasks in the list, display No tasks instead. The number of active tasks can be retrieved with the following SQL query:
-SELECT count(*) FROM Task WHERE completed=0;-