Skip to content

Commit

Permalink
Merge pull request #211 from Divyesh000/detailedorder
Browse files Browse the repository at this point in the history
create a detailed order page
  • Loading branch information
creme332 authored Jun 1, 2024
2 parents 04def54 + 93721c5 commit 7424b30
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 35 deletions.
22 changes: 19 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,24 @@ includes:

For more details, see the [software requirements specification](docs/SOFTWARE_SPECS.md).

The code for the admin website is found in a separate repository.
This repository contains the code for the client website and the API. The code for the admin website is found in a
separate repository.

## Main features

- MVC pattern
- Semantic URL routing
- Email-based password recovery
- Email notification on order
- Testing with phpUnit
- Email notification on checkout
- Integration testing with phpUnit
- Mobile-responsive website
- Utilizes Webpack for efficient code bundling and compatibility with older browsers.
- Product review system with nested comments
- Fuzzy searching on shop page
- Pagination
- SEO optimized
- REST API
- API testing with Guzzler and phpUnit

## Documentation

Expand All @@ -58,3 +60,17 @@ Attribution-ShareAlike
- https://github.com/kevinisaac/php-mvc
4. The filesystem was inspired by https://github.com/php-pds/sklseleton
5. Additional references are included within the code itself.

# Todo

Add `X-TEST-ENV` to the header of your request and set its value to `testing` if you want to use the testing database.
This is required when running tests for API. Without this key-value pair, the production database will be used.

USE DOCKER PHP

- read guzzle documentation. read base_uri
- test database is being used
- add variable to .env

line 18 in Reviews API is redundant
use correct namespace
78 changes: 78 additions & 0 deletions src/controllers/Orders.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

declare(strict_types=1);

namespace Steamy\Controller;

use Steamy\Core\Controller;
use Steamy\Core\Utility;
use Steamy\Model\Order;
use Steamy\Model\OrderProduct;

class Orders
{
use Controller;

private array $view_data = [];

private function validateURL(): bool
{
$url = Utility::getURL();
// Check if the URL matches the expected pattern
return preg_match('/^orders\/\d+$/', $url) === 1;
}

private function getOrderIDFromURL(): ?int
{
if ($this->validateURL()) {
$url = Utility::getURL();
$parts = explode('/', $url);
// Check if the last part of the URL is a valid integer
$lastPart = end($parts);
if (is_numeric($lastPart)) {
return (int)$lastPart;
} else {
return null;
}
}
return null;
}


private function handleInvalidURL(): void
{
if (!$this->validateURL()) {
(new Error())->handlePageNotFoundError();
die();
}
}

public function index(): void
{
$this->handleInvalidURL();

$order_id = $this->getOrderIDFromURL();
if ($order_id === null) {
(new Error())->handlePageNotFoundError();
return;
}

$order = Order::getByID($order_id);
if (!$order) {
(new Error())->handlePageNotFoundError();
return;
}

$order_products = Order::getOrderProducts($order->getOrderID());

$this->view_data['order'] = $order;
$this->view_data['line_items'] = $order_products;

$this->view(
'orders',
$this->view_data,
'Order #' . $order_id,
enableIndexing: false
);
}
}
2 changes: 1 addition & 1 deletion src/controllers/Profile.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public function cancelOrder(): void
}

// Cancel the order
$order->deleteOrder();
$order->cancelOrder();
}

private function handleProfileEditSubmission(): void
Expand Down
12 changes: 3 additions & 9 deletions src/models/Order.php
Original file line number Diff line number Diff line change
Expand Up @@ -260,21 +260,15 @@ public static function getByID(int $order_id): ?Order
}

/**
* Deletes the order and associated line items from the database.
* Cancels the order and associated line items from the database.
*/
public function deleteOrder(): void
public function cancelOrder(): void
{
$conn = self::connect();
$conn->beginTransaction();

try {
// Delete line items first
$query = "DELETE FROM order_product WHERE order_id = :order_id";
$stm = $conn->prepare($query);
$stm->execute(['order_id' => $this->order_id]);

// Delete the order itself
$query = "DELETE FROM `order` WHERE order_id = :order_id";
$query = "UPDATE `order` SET status = 'cancelled' WHERE order_id = :order_id";
$stm = $conn->prepare($query);
$stm->execute(['order_id' => $this->order_id]);

Expand Down
43 changes: 25 additions & 18 deletions src/models/OrderProduct.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,29 +87,36 @@ public function validate(): array
return $errors;
}

public static function getByID(int $order_id, int $product_id): ?OrderProduct
public static function getByID(int $order_id, int $product_id = null): ?OrderProduct
{
$query = <<< EOL
select * from order_product
where order_id = :order_id and product_id = :product_id
EOL;
$query = 'SELECT * FROM order_product WHERE order_id = :order_id';
$params = ['order_id' => $order_id];

$result = self::query($query, ['order_id' => $order_id, 'product_id' => $product_id]);
if (empty($result)) {
return null;
}
$result = $result[0];
if ($product_id !== null) {
$query .= ' AND product_id = :product_id';
$params['product_id'] = $product_id;
}

return new OrderProduct(
product_id: $result->product_id,
cup_size: $result->cup_size,
milk_type: $result->milk_type,
quantity: $result->quantity,
unit_price: (float)$result->unit_price,
order_id: $result->order_id,
);
$result = self::query($query, $params);
if (empty($result)) {
return null;
}

// Assuming there's only one product for a given order if product_id is not provided
if ($product_id === null) {
$result = $result[0];
}

return new OrderProduct(
product_id: $result->product_id,
cup_size: $result->cup_size,
milk_type: $result->milk_type,
quantity: $result->quantity,
unit_price: (float)$result->unit_price,
order_id: $result->order_id,
);
}

public function getOrderID(): int
{
return $this->order_id;
Expand Down
48 changes: 48 additions & 0 deletions src/views/Orders.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

declare(strict_types=1);

/**
* @var Order $order Current order
* @var OrderProduct[] $line_items Line items for current order
*/

use Steamy\Model\Order;
use Steamy\Model\OrderProduct;

?>

<main class="container">
<h1>Order #<?= filter_var($order->getOrderID(), FILTER_SANITIZE_NUMBER_INT); ?></h1>
<section>
<h2>Order Details</h2>
<p><strong>Order ID:</strong> <?= filter_var($order->getOrderID(), FILTER_SANITIZE_NUMBER_INT); ?></p>
<p><strong>Date:</strong> <?= htmlspecialchars($order->getCreatedDate()->format('Y-m-d H:i:s')) ?></p>
<p><strong>Status:</strong> <?= htmlspecialchars(ucfirst($order->getStatus()->value)) ?></p>
<p><strong>Total Price:</strong> $<?= htmlspecialchars(number_format($order->calculateTotalPrice(), 2)) ?></p>
</section>

<section>
<h2>Order Items</h2>
<table>
<tr>
<th>Product Name</th>
<th>Quantity</th>
<th>Milk Type</th>
<th>Cup Size</th>
<th>Unit Price</th>
</tr>
<?php
foreach ($line_items as $item): ?>
<tr>
<td><?= htmlspecialchars($item->getProductName()) ?></td>
<td><?= filter_var($item->getQuantity(), FILTER_SANITIZE_NUMBER_INT) ?></td>
<td><?= htmlspecialchars($item->getMilkType()) ?></td>
<td><?= htmlspecialchars($item->getCupSize()) ?></td>
<td>$<?= (number_format($item->getUnitPrice(), 2)) ?></td>
</tr>
<?php
endforeach; ?>
</table>
</section>
</main>
14 changes: 10 additions & 4 deletions src/views/Profile.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
$totalPrice = htmlspecialchars(number_format($order->calculateTotalPrice(), 2));

// Determine button states
$cancelDisabled = $order->getStatus()->value === 'completed' ? 'disabled' : '';
$cancelDisabled = ($order->getStatus()->value === 'completed' || $order->getStatus()->value === 'cancelled') ? 'disabled' : '';

echo <<< EOL
<tr>
Expand All @@ -112,17 +112,22 @@
<td>
<form style="display: flex; gap:1em;" method="post">
<a style="height: 60px" class="secondary" href="/orders/$id" role="button">View</a>
<input type="hidden" name="order_id" value="$id">
<button type="submit" name="cancel_order" $cancelDisabled>Cancel</button>
<button type="submit" name="reorder">Reorder</button>
<button style="height: 60px" type="submit" name="reorder">Reorder</button>
<button style="height: 60px" type="submit" name="cancel_order" $cancelDisabled>Cancel</button>
</form>
</td>
</tr>
EOL;
}

?>


</table>
</figure>

</div>

<div id="Settings" class="tabcontent">
Expand Down Expand Up @@ -169,9 +174,10 @@
<form>
<button type="submit" name="account_delete_submit">Delete</button>
</form>

</article>
</div>
</div>
</main>

<script src="/js/profile_view.bundle.js"></script>
<script src="/js/profile_view.bundle.js"></script>

0 comments on commit 7424b30

Please sign in to comment.