Skip to content

Commit

Permalink
Implement product search
Browse files Browse the repository at this point in the history
  • Loading branch information
chocbic172 committed Mar 22, 2024
1 parent 3feddf2 commit 306e74f
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 19 deletions.
2 changes: 1 addition & 1 deletion checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@
- [x] PHP item page
- [x] Product reviews / scores
- [x] Verified users can post reviews
- [ ] Advanced search
- [x] Advanced search
- [ ] Checkout mechanism
- [x] Secure password storage / verification
53 changes: 37 additions & 16 deletions root/products.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,26 @@

$db = new DBConnection();

function generateRating(string $productId, $db) {
/**
* Generates a graphical view of the rating of the item `$productId`
*/
function generateRating(string $productId, DBConnection $db) {
if (intval($db->getRatingForProduct($productId)) > 0) {
return str_repeat('', intval($db->getRatingForProduct($productId)));
} else {
return 'No ratings yet!';
}
}

function getProductsOfType(string $productType, DBConnection $db) {
$result = $db->getProductsOfType($productType);
/**
* Generates a collection of HTML products from a `mysqli_result` object
*/
function renderProductsFromSQL(mysqli_result $products, DBConnection $db) {
$output = "";

if ($result->num_rows > 0) {
if ($products->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
while($row = $products->fetch_assoc()) {
$output .= '<a href="./item.php?id='.$row["product_id"].'"><div class="col-33">'.
'<div class="product">'.
'<img src="assets/'.$row["product_image"].'" alt="'.$row["product_title"].'">'.
Expand All @@ -38,22 +43,28 @@ function getProductsOfType(string $productType, DBConnection $db) {
return $output;
}

function generateProductsSection(string $productType, string $productTitle, DBConnection $db) {
/**
* Generates a "product section" page component
*/
function generateProductsSection(mysqli_result $products, string $sectionTitle, DBConnection $db) {
return '
<div class="product-section">
<h2>'.$productTitle.'</h2>
<h2>'.$sectionTitle.'</h2>
<div class="row product-row">
'.getProductsOfType($productType, $db).'
'.renderProductsFromSQL($products, $db).'
</div>
</div>
';
}

/**
* Get ALL products in the database, categorised by item type
*/
function getAllProducts(DBConnection $db) {
$productSections = "";
$productSections .= generateProductsSection('UCLan Hoodie', 'Hoodie', $db);
$productSections .= generateProductsSection('UCLan Logo Jumper', 'Jumper', $db);
$productSections .= generateProductsSection('UCLan Logo TShirt', 'TShirt', $db);
$productSections .= generateProductsSection($db->getProductsOfType('UCLan Hoodie'), 'Hoodie', $db);
$productSections .= generateProductsSection($db->getProductsOfType('UCLan Logo Jumper'), 'Jumper', $db);
$productSections .= generateProductsSection($db->getProductsOfType('UCLan Logo TShirt'), 'TShirt', $db);
return $productSections;
}

Expand Down Expand Up @@ -102,6 +113,15 @@ function getAllProducts(DBConnection $db) {
</a>
</div>

<div class="search-section">
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"])?>" method="get">
<input type="text" name="q" id="search" class="search-bar"
placeholder="Type Search Here..." value="<?php echo isset($_GET['q']) ? $_GET['q']: ''?>">

<input type="submit" value="Search" class="search-submit">
</form>
</div>

<!--
We GET the filter data to the server so it can be navigated through using the browser search history.
MDN Docs:
Expand All @@ -123,13 +143,15 @@ function getAllProducts(DBConnection $db) {
// is submitted via a URL naviation event, as opposed to through a form.
// We show all products if a) there is no applied filter or b) the
// requested type is invalid
if (isset($_GET['type'])) {
if (isset($_GET['q'])) {
echo generateProductsSection($db->getProductsFromSearch($_GET['q']), 'Search Results', $db);
} else if (isset($_GET['type'])) {
if ($_GET['type'] == "hoodies") {
echo generateProductsSection('UCLan Hoodie', 'Hoodie', $db);
echo generateProductsSection($db->getProductsOfType('UCLan Hoodie'), 'Hoodie', $db);
} else if ($_GET['type'] == "jumpers") {
echo generateProductsSection('UCLan Logo Jumper', 'Jumper', $db);
echo generateProductsSection($db->getProductsOfType('UCLan Logo Jumper'), 'Jumper', $db);
} else if ($_GET['type'] == "tshirts") {
echo generateProductsSection('UCLan Logo TShirt', 'TShirt', $db);
echo generateProductsSection($db->getProductsOfType('UCLan Logo Tshirt'), 'Tshirt', $db);
} else {
echo getAllProducts($db);
}
Expand All @@ -138,7 +160,6 @@ function getAllProducts(DBConnection $db) {
}
?>


<!-- Site footer -->
<?php include 'components/footer.inc.php' ?>
</body>
Expand Down
35 changes: 35 additions & 0 deletions root/styles/products.css
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,41 @@ https://developer.mozilla.org/en-US/docs/Web/CSS/scale */
width: 70%;
}

/*
Search design
*/

.search-section {
padding-top: 20px;
text-align: center;
padding-bottom: 20px;
}

.search-bar {
border: 0;
border-bottom: 1px solid black;

font-size: 1.5em;
font-weight: 400;

padding: 10px;
width: 30%;
}

.search-bar:focus {
outline: 0;
}

.search-submit {
background-color: #cacaca;
color: black;
border: none;
border-radius: 10px;
padding: 5px 10px;
cursor: pointer;
font-size: 1.5em;
}

/*
Responsive design
*/
Expand Down
19 changes: 17 additions & 2 deletions root/utils/database.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class DBConnection {

/**
* Connect to the database using the environment configuration
*/
*/
public function __construct() {
require('env.php');

Expand All @@ -47,7 +47,7 @@ public function __construct() {

/**
* Clean up trailing database connections
*/
*/
function __destruct() {
if ($this->conn) {
$this->conn->close();
Expand All @@ -67,6 +67,21 @@ public function getProductsOfType(string $type) {
return $result;
}

/**
* Returns all products that match the search query an `sqli_result`
*/
public function getProductsFromSearch(string $searchQuery) {
// The LIKE operator is used here to "search" the database for products with
// similar titles. W3 Schools Ref: https://www.w3schools.com/sql/sql_like.asp
$sql_query = $this->conn->prepare("SELECT * FROM ".$this->products_table." WHERE product_title LIKE ?");
$sql_query->execute(['%'.$searchQuery.'%']);

$result = $sql_query->get_result();
$sql_query->close();

return $result;
}

/**
* Returns the information of product with `$id`
*
Expand Down

0 comments on commit 306e74f

Please sign in to comment.