Skip to content

Lab 6: Implementing UPDATE and DELETE Operations

In this lab, you will implement the UPDATE and DELETE operations in your admin panel.

  • In Part I, you will implement the UPDATE operation, which allows administrators to edit existing products. Like the CREATE operation, it involves two steps: displaying a pre-populated edit form (GET request) and handling the form submission (POST request).
  • In Part II, you will implement the DELETE operation, which allows administrators to remove products from the database.
  • You will also modify the product listing page from Lab 5 by adding an Actions column with Edit and Delete buttons for each product.

By completing this lab, you will:

  • Add an Actions column to the product listing table for row-level operations.
  • Implement the UPDATE operation with GET (display pre-populated form) and POST (handle submission) routes.
  • Fetch a single record by ID and pass it to a view for editing.
  • Build an edit form whose fields are pre-populated with existing data.
  • Implement the DELETE operation with a confirmation dialog to prevent accidental deletions.
  • Reuse the PRG pattern and FlashMessage integration from Lab 5.

Before starting this lab, ensure you have:

  • Completed Lab 5 (READ & CREATE operations with ProductsModel, ProductsController, and product listing view).
  • The product listing page (/admin/products) is working correctly.

In this part, you will add an Actions column to the product listing and implement the UPDATE operation.

Step 1: Add an Actions Column to the Product Listing

Section titled “Step 1: Add an Actions Column to the Product Listing”

Objective: Modify the product listing view from Lab 5 to include an Actions column with an Edit button for each product.

Instructions:

  1. Open app/Views/admin/products/products.IndexView.php
  2. Add an Actions column header to the <thead>:
<th>Actions</th>
  1. Inside the <tbody> loop, add a table cell with an Edit link for each product:
<td>
<a href="<?= APP_BASE_URL ?>/admin/products/<?= $product['id'] ?>/edit"
class="btn btn-sm btn-warning">
Edit
</a>
</td>
  1. Save the file

Objective: Add two routes for the UPDATE operation inside the /admin route group.

Instructions:

  1. Open app/Routes/web-routes.php
  2. Inside the existing /admin group, add two routes:
app/Routes/web-routes.php
$app->group('/admin', function ($group) {
// ... existing routes ...
// TODO: Add GET route for /products/{id}/edit
// - Controller: ProductsController::class, 'edit'
// - Named route: 'products.edit'
// TODO: Add POST route for /products/{id}
// - Controller: ProductsController::class, 'update'
});
  1. Save the file

Objective: Add a method to ProductsModel that fetches a single product by its ID.

Instructions:

  1. Open app/Domain/Models/ProductsModel.php
  2. Add the following method:
app/Domain/Models/ProductsModel.php
public function findById(int $id): array|false
{
// TODO: Execute a SELECT query to fetch a single product by ID
// - Use $this->selectOne() with a WHERE clause
// - Return the product as an associative array, or false if not found
}
  1. Add a second method to update a product:
app/Domain/Models/ProductsModel.php
public function update(int $id, array $data): int
{
// TODO: Execute an UPDATE query using $this->execute()
// - Update: category_id, name, price, description
// - Use named parameters (:category_id, :name, :price, :description, :id)
// - Return the number of affected rows
}
  1. Save the file

Objective: Add edit() and update() methods to ProductsController.

Instructions:

  1. Open app/Controllers/ProductsController.php
  2. Add the following two methods:
app/Controllers/ProductsController.php
public function edit(Request $request, Response $response, array $args): Response
{
// TODO: 1. Get the product ID from $args['id']
// TODO: 2. Fetch the product using $this->productsModel->findById()
// TODO: 3. If product not found, set an error flash message and redirect to 'products.index'
// TODO: 4. Fetch all categories using $this->productsModel->getAllCategories()
// TODO: 5. Create a $data array with 'title', 'product', and 'categories' keys
// TODO: 6. Render the view 'admin/products/products.EditView.php' and pass $data
}

Method 2: update() - Handle Form Submission

Section titled “Method 2: update() - Handle Form Submission”
app/Controllers/ProductsController.php
public function update(Request $request, Response $response, array $args): Response
{
// TODO: 1. Get the product ID from $args['id']
// TODO: 2. Get form data using $request->getParsedBody()
// TODO: 3. Validate required fields (name and price)
// - If validation fails, set an error flash message and redirect back to 'products.edit'
// TODO: 4. Update the product using $this->productsModel->update()
// TODO: 5. Set a success flash message
// TODO: 6. Redirect to the product list ('products.index')
}
  1. Save the file

Objective: Build an edit form that is pre-populated with the product’s existing data.

Instructions:

  1. Navigate to app/Views/admin/products/
  2. Create a new file named products.EditView.php
  3. Set up the view structure:
app/Views/admin/products/products.EditView.php
<?php
use App\Helpers\ViewHelper;
ViewHelper::loadAdminHeader($title);
?>
<form method="POST" action="<?= APP_BASE_URL ?>/admin/products/<?= $product['id'] ?>">
<!-- TODO: Add a select dropdown for category (pre-select the product's current category) -->
<!-- Use ViewHelper::renderSelectOptions($categories, $product['category_id'], 'id', 'name') -->
<!-- TODO: Add input field for product name (pre-populated with $product['name']) -->
<!-- TODO: Add input field for price (pre-populated with $product['price']) -->
<!-- TODO: Add textarea for description (pre-populated with $product['description']) -->
<!-- TODO: Add submit button ("Update Product") -->
<!-- TODO: Add cancel link back to the admin product list -->
</form>
<?php ViewHelper::loadAdminFooter(); ?>
  1. Save the file

Objective: Verify that the UPDATE operation works correctly.

Instructions:

  1. Visit http://localhost/[your-app-name]/admin/products in your browser
  2. Verify the Edit button appears in the Actions column for each product
  3. Click an Edit button and verify:
    • The edit form loads with the product’s current data pre-populated
    • Submitting with empty required fields shows an error flash message
    • Submitting with valid data updates the product, shows a success flash message, and redirects to the product list
    • The updated values are reflected in the product listing

In this part, you will add the ability to delete products from the admin panel.

Step 7: Add a Delete Button to the Product Listing

Section titled “Step 7: Add a Delete Button to the Product Listing”

Objective: Add a Delete button next to the Edit button in the Actions column.

Instructions:

  1. Open app/Views/admin/products/products.IndexView.php
  2. In the Actions <td> (where you added the Edit button in Step 1), add a Delete link:
<a href="<?= APP_BASE_URL ?>/admin/products/<?= $product['id'] ?>/delete"
class="btn btn-sm btn-danger"
onclick="return confirm('Are you sure you want to delete this product?')">
Delete
</a>
  1. Save the file

Objective: Add a route for the DELETE operation inside the /admin route group.

Instructions:

  1. Open app/Routes/web-routes.php
  2. Inside the existing /admin group, add one route:
app/Routes/web-routes.php
$app->group('/admin', function ($group) {
// ... existing routes ...
// TODO: Add GET route for /products/{id}/delete
// - Controller: ProductsController::class, 'delete'
// - Named route: 'products.delete'
});
  1. Save the file

Objective: Add a method to ProductsModel that deletes a product by its ID.

Instructions:

  1. Open app/Domain/Models/ProductsModel.php
  2. Add the following method:
app/Domain/Models/ProductsModel.php
public function delete(int $id): int
{
// TODO: Execute a DELETE query using $this->execute()
// - Use a WHERE clause with named parameter :id
// - Return the number of affected rows
}
  1. Save the file

Objective: Add a delete() method to ProductsController that removes a product and redirects back to the list.

Instructions:

  1. Open app/Controllers/ProductsController.php
  2. Add the following method:
app/Controllers/ProductsController.php
public function delete(Request $request, Response $response, array $args): Response
{
// TODO: 1. Get the product ID from $args['id']
// TODO: 2. Delete the product using $this->productsModel->delete()
// TODO: 3. Set a success flash message
// TODO: 4. Redirect to the product list ('products.index')
}
  1. Save the file

Objective: Verify that the DELETE operation works correctly.

Instructions:

  1. Visit http://localhost/[your-app-name]/admin/products in your browser
  2. Verify the Delete button appears next to each Edit button
  3. Click a Delete button and verify:
    • A confirmation dialog appears asking “Are you sure?”
    • Clicking “Cancel” does nothing
    • Clicking “OK” deletes the product, shows a success flash message, and redirects to the product list
    • The deleted product no longer appears in the list