Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified .DS_Store
Binary file not shown.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.DS_Store
04/.DS_Store
9 changes: 9 additions & 0 deletions 03/03_make_it_maintainable/footer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php
// footer.php
// Shared footer HTML (reused across pages).
?>
<hr>
<p>&copy; 2026</p>
</body>
</html>

13 changes: 13 additions & 0 deletions 03/03_make_it_maintainable/header.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php
// header.php
// Shared page header HTML (reused across pages to avoid repetition).
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>My PHP Page</title>
</head>
<body>
<h1>Welcome</h1>
<hr>
48 changes: 22 additions & 26 deletions 03/03_make_it_maintainable/index.php
Original file line number Diff line number Diff line change
@@ -1,34 +1,30 @@
<?php
/* What's the Problem?
- PHP logic + HTML in one file
- Works, but not scalable
- Repetition will become a problem
// What I learned: Using arrays + loops + a single template page makes the site easier to maintain.
// I’ll apply this in Course Project Phase One instead of duplicating pages.

How can we refactor this code so it’s easier to maintain?
*/
require_once __DIR__ . '/header.php';

$items = ["Home", "About", "Contact"];
$pages = [
'home' => ['title' => 'Home', 'content' => 'Welcome to my PHP page.'],
'about' => ['title' => 'About', 'content' => 'This is the About section.'],
'contact' => ['title' => 'Contact', 'content' => 'This is the Contact section.'],
];

$current = $_GET['page'] ?? 'home';
if (!isset($pages[$current])) {
$current = 'home';
}
?>

<!DOCTYPE html>
<html>
<head>
<title>My PHP Page</title>
</head>
<body>
<nav>
<ul>
<?php foreach ($pages as $key => $page): ?>
<li><a href="index.php?page=<?= $key ?>"><?= $page['title'] ?></a></li>
<?php endforeach; ?>
</ul>
</nav>

<h1>Welcome</h1>
<h2><?= $pages[$current]['title'] ?></h2>
<p><?= $pages[$current]['content'] ?></p>

<ul>
<?php foreach ($items as $item): ?>
<li><?= $item ?></li>
<?php endforeach; ?>
</ul>

<footer>
<p>&copy; 2026</p>
</footer>

</body>
</html>
<?php require_once __DIR__ . '/footer.php'; ?>
Binary file added 04/.DS_Store
Binary file not shown.
Binary file added 04/assets/bitumi.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Submodule COMP1006_Winter2026 added at adeb2b
4 changes: 4 additions & 0 deletions 04/includes/footer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<footer>
<p> Bake It Til You Make It - COMP1006 </p>
<p> Week 4 - Form Validation</p>
</footer>
25 changes: 25 additions & 0 deletions 04/includes/header.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Week 4 - Form Validation </title>
<link href="styles/main.css" rel="stylesheet">
</head>

<body>
<header>
<h1 class="site-title">
<img
src="assets/bitumi.png"
alt="Bake It Til You Make It Bakery"
class="logo">
</h1>
<nav>
<a href="/"> Home </a>
<a href="#"> About </a>
<a href="#"> Order Online </a>
<a href="#"> Contact </a>
</nav>
</header>
113 changes: 113 additions & 0 deletions 04/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<?php require "includes/header.php" ?>
<main>
<h2> Order Online - Easy & Simple (And Totally Secure...) 🧁</h2>
<form action="process.php" method="post">
<!-- STEP ONE - Add Client Side Validation with HTML -->
<!-- Customer Information -->
<fieldset>
<legend>Customer Information</legend>
<label for="first_name">First name</label>
<input type="text" id="first_name" name="first_name" required>
<label for="last_name">Last name</label>
<input type="text" id="last_name" name="last_name" required>
<label for="phone">Phone number</label>
<input type="tel" id="phone" name="phone" placeholder="555-123-4567" required>
<label for="address">Address</label>
<input type="text" id="address" name="address" required>
<label for="email">Email</label>
<input type="email" id="email" name="email" required>
</fieldset>

<!-- Order Details -->
<fieldset>
<legend>Order Details</legend>

<p>
Enter a quantity for each item (use 0 if you don't want it).
</p>

<table border="1" cellpadding="8" cellspacing="0">
<thead>
<tr>
<th scope="col">Baked Treat</th>
<th scope="col">Quantity</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Chaos Croissant 🥐</th>
<td>
<label for="chaos_croissant" class="visually-hidden">Chaos Croissant quantity</label>
<input type="number" id="chaos_croissant" name="items[chaos_croissant]" min="0" max="24" value="0">
</td>
</tr>

<tr>
<th scope="row">Midnight Muffin 🌙</th>
<td>
<label for="midnight_muffin" class="visually-hidden">Midnight Muffin quantity</label>
<input type="number" id="midnight_muffin" name="items[midnight_muffin]" min="0" max="24" value="0">
</td>
</tr>

<tr>
<th scope="row">Existential Éclair 🤔</th>
<td>
<label for="existential_eclair" class="visually-hidden">Existential Éclair quantity</label>
<input type="number" id="existential_eclair" name="items[existential_eclair]" min="0" max="24"
value="0">
</td>
</tr>

<tr>
<th scope="row">Procrastination Cookie ⏰</th>
<td>
<label for="procrastination_cookie" class="visually-hidden">Procrastination Cookie quantity</label>
<input type="number" id="procrastination_cookie" name="items[procrastination_cookie]" min="0" max="24"
value="0">
</td>
</tr>

<tr>
<th scope="row">Finals Week Brownie 📚</th>
<td>
<label for="finals_week_brownie" class="visually-hidden">Finals Week Brownie quantity</label>
<input type="number" id="finals_week_brownie" name="items[finals_week_brownie]" min="0" max="24"
value="0">
</td>
</tr>

<tr>
<th scope="row">Victory Cinnamon Roll 🏆</th>
<td>
<label for="victory_cinnamon_roll" class="visually-hidden">Victory Cinnamon Roll quantity</label>
<input type="number" id="victory_cinnamon_roll" name="items[victory_cinnamon_roll]" min="0" max="24"
value="0">
</td>
</tr>
</tbody>
</table>

</fieldset>

<fieldset>
<legend>Additional Comments</legend>

<p>
<label for="comments">Comments (optional)</label><br>
<textarea id="comments" name="comments" rows="4"
placeholder="Allergies, delivery instructions, custom messages..."></textarea>
</p>
</fieldset>

<p>
<button type="submit">Place Order</button>
</p>

</form>
</main>
</body>

</html>

<?php require "includes/footer.php" ?>
Empty file added 04/lab-4 /css/main.css
Empty file.
Empty file added 04/lab-4 /includes/footer.php
Empty file.
Empty file added 04/lab-4 /includes/header.php
Empty file.
Empty file added 04/lab-4 /index.php
Empty file.
Empty file added 04/lab-4 /process.php
Empty file.
Empty file added 04/lab-4 /send_email.php
Empty file.
154 changes: 154 additions & 0 deletions 04/process.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
<?php
require "includes/header.php";
/**
* process.php
* -----------
* PURPOSE:
* - Receive form data from an HTML form
* - Sanitize and validate user input
* - Build and send an email to the client
* - Display a confirmation message
*
* This version includes:
* - filter_input() for sanitizing
* - filter_var() for validation
*/

// ---------------------------------------------------------
// 1) Ensure the form was submitted using POST
// ---------------------------------------------------------
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
echo "<p>This page expects a POST form submission.</p>";
exit;
}

// ---------------------------------------------------------
// 2) Sanitize data using filter_input()
// ---------------------------------------------------------
// Instructor note:
// - filter_input() reads from INPUT_POST instead of $_POST
// - FILTER_SANITIZE_SPECIAL_CHARS prevents HTML injection
$firstName = filter_input(INPUT_POST, 'first_name', FILTER_SANITIZE_SPECIAL_CHARS);
$lastName = filter_input(INPUT_POST, 'last_name', FILTER_SANITIZE_SPECIAL_CHARS);
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$phone = filter_input(INPUT_POST, 'phone', FILTER_SANITIZE_SPECIAL_CHARS);
$address = filter_input(INPUT_POST, 'address', FILTER_SANITIZE_SPECIAL_CHARS);
$comments = filter_input(INPUT_POST, 'comments', FILTER_SANITIZE_SPECIAL_CHARS);

// ---------------------------------------------------------
// 3) Access array-based item data
// ---------------------------------------------------------
// - filter_input() does not work well with nested arrays
// - Array inputs must be accessed directly
$items = $_POST['items'] ?? [];

// ---------------------------------------------------------
// 4) Validate required fields
// ---------------------------------------------------------
$errors = [];

// Required text fields
if ($firstName === null || $firstName === '') {
$errors[] = "First name is required.";
}

if ($lastName === null || $lastName === '') {
$errors[] = "Last name is required.";
}

// Email validation
if ($email === null || $email === '') {
$errors[] = "Email address is required.";
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = "Email address must be a valid email.";
}

// Phone validation (simple, teaching-friendly)
if ($phone === null || $phone === '') {
$errors[] = "Phone number is required.";
} elseif (!filter_var($phone, FILTER_VALIDATE_REGEXP, [
'options' => ['regexp' => '/^[0-9\-\+\(\)\s]{7,25}$/']
])) {
$errors[] = "Phone number format is invalid.";
}

if ($address === null || $address === '') {
$errors[] = "Address is required.";
}

// ---------------------------------------------------------
// 5) Validate item quantities
// ---------------------------------------------------------
// Instructor note:
// - We require at least one item with quantity > 0
$itemsOrdered = [];

foreach ($items as $item => $quantity) {
if (filter_var($quantity, FILTER_VALIDATE_INT) !== false && $quantity > 0) {
$itemsOrdered[$item] = $quantity;
}
}

if (count($itemsOrdered) === 0) {
$errors[] = "Please order at least one item.";
}

// ---------------------------------------------------------
// 6) If errors exist, display them and stop
// ---------------------------------------------------------

?>


<main>
<?php if (!empty($errors)) {
?>
<h1>There was a problem with your order</h1>

<ul>
<?php foreach ($errors as $error): ?>
<li><?= $error ?></li>
<?php endforeach; ?>
</ul>

<p>
<a href="index.php">Return to the form</a>
</p>
</main>
</body>
</html>
<?php
exit;
}
?>
<h1>Thank You for Your Order! 🧁</h1>

<p>
Thanks <strong><?= $firstName ?></strong>!
Your order has been received and sent to the bakery.
</p>

<h2>Your Order Details</h2>

<p><strong>Name:</strong> <?= $firstName ?> <?= $lastName ?></p>
<p><strong>Phone:</strong> <?= $phone ?></p>
<p><strong>Address:</strong> <?= $address ?></p>

<h3>Items Ordered</h3>
<ul>
<?php foreach ($items as $item => $quantity): ?>
<li><?= $item ?> — <?= $quantity ?></li>
<?php endforeach; ?>
</ul>

<h3>Additional Comments</h3>
<p><?= $comments === "" ? "(none)" : $comments ?></p>

<p>
A confirmation has been sent to the bakery.
</p>

<a href="index.php">Place another order</a>
</main>

<?php require "includes/footer.php"; ?>
Loading