From ccc3280a90da47999958f6f6908f4b7065498332 Mon Sep 17 00:00:00 2001 From: divyesh000 Date: Thu, 9 May 2024 17:45:30 +0400 Subject: [PATCH 01/10] complete api/Products controller --- src/controllers/api/Products.php | 225 ++++++++++++++++++++++++++++--- src/models/Product.php | 11 ++ 2 files changed, 220 insertions(+), 16 deletions(-) diff --git a/src/controllers/api/Products.php b/src/controllers/api/Products.php index 1b1f78d..c6a37e3 100644 --- a/src/controllers/api/Products.php +++ b/src/controllers/api/Products.php @@ -6,52 +6,245 @@ use Steamy\Model\Product; -/** - * Handles /products route of api - */ class Products { + /** + * Get the list of all products available in the store. + */ private function getProducts(): void { - $all_products = Product::getAll(); + // Retrieve all products from the database + $allProducts = Product::getAll(); + + // Convert products to array format $result = []; - foreach ($all_products as $product) { + foreach ($allProducts as $product) { $result[] = $product->toArray(); } + + // Return JSON response echo json_encode($result); } - private function addProduct(): void + /** + * Get the details of a specific product by its ID. + */ + private function getProductById(int $productId): void + { + // Retrieve product details from the database + $product = Product::getByID($productId); + + // Check if product exists + if ($product === null) { + // Product not found, return 404 + http_response_code(404); + echo json_encode(['error' => 'Product not found']); + return; + } + + // Return JSON response + echo json_encode($product->toArray()); + } + + /** + * Get the list of product categories. + */ + private function getProductCategories(): void + { + // Retrieve all product categories from the database + $categories = Product::getCategories(); + + // Return JSON response + echo json_encode($categories); + } + + + /** + * Create a new product entry in the database. + */ + private function createProduct(): void { + // Retrieve POST data + $postData = json_decode(file_get_contents("php://input"), true); + + // Check if required fields are present + $requiredFields = ['name', 'calories', 'img_url', 'img_alt_text', 'category', 'price', 'description', 'created_date']; + foreach ($requiredFields as $field) { + if (!isset($postData[$field])) { + // Required field is missing, return 400 Bad Request + http_response_code(400); + echo json_encode(['error' => "Missing required field: $field"]); + return; + } + } + + // Create a new Product object + $newProduct = new Product( + $postData['name'], + (int)$postData['calories'], + $postData['img_url'], + $postData['img_alt_text'], + $postData['category'], + (float)$postData['price'], + $postData['description'], + $postData['created_date'] + ); + + // Save the new product to the database + if ($newProduct->save()) { + // Product created successfully, return 201 Created + http_response_code(201); + echo json_encode(['message' => 'Product created successfully', 'product_id' => $newProduct->getProductID()]); + } else { + // Failed to create product, return 500 Internal Server Error + http_response_code(500); + echo json_encode(['error' => 'Failed to create product']); + } } - private function deleteProduct(): void + /** + * Delete a product with the specified ID. + */ + private function deleteProduct(int $productId): void { + // Retrieve the product by ID + $product = Product::getByID($productId); + + // Check if product exists + if ($product === null) { + // Product not found, return 404 + http_response_code(404); + echo json_encode(['error' => 'Product not found']); + return; + } + + // Attempt to delete the product + if ($product->delete()) { + // Product successfully deleted + http_response_code(204); // No Content + } else { + // Failed to delete the product + http_response_code(500); // Internal Server Error + echo json_encode(['error' => 'Failed to delete product']); + } } - private function updateProduct(): void + + /** + * Update the details of a product with the specified ID. + */ + private function updateProduct(int $productId): void { + // Retrieve PUT request data + $putData = json_decode(file_get_contents("php://input"), true); + + // Check if PUT data is valid + if ($putData === null) { + // Invalid JSON data + http_response_code(400); // Bad Request + echo json_encode(['error' => 'Invalid JSON data']); + return; + } + + // Retrieve existing product + $product = Product::getByID($productId); + + // Check if product exists + if ($product === null) { + // Product not found + http_response_code(404); // Not Found + echo json_encode(['error' => 'Product not found']); + return; + } + + // Update product attributes + if (isset($putData['name'])) { + $product->setName($putData['name']); + } + if (isset($putData['calories'])) { + $product->setCalories(intval($putData['calories'])); + } + if (isset($putData['img_url'])) { + $product->setImgUrl($putData['img_url']); + } + if (isset($putData['img_alt_text'])) { + $product->setImgAltText($putData['img_alt_text']); + } + if (isset($putData['category'])) { + $product->setCategory($putData['category']); + } + if (isset($putData['price'])) { + $product->setPrice(floatval($putData['price'])); + } + if (isset($putData['description'])) { + $product->setDescription($putData['description']); + } + + // Validate updated product attributes + $errors = $product->validate(); + if (!empty($errors)) { + // Validation errors + http_response_code(400); // Bad Request + echo json_encode(['error' => 'Validation failed', 'errors' => $errors]); + return; + } + + // Save updated product to the database + if ($product->save()) { + // Product updated successfully + http_response_code(200); // OK + echo json_encode(['message' => 'Product updated successfully']); + } else { + // Failed to update product + http_response_code(500); // Internal Server Error + echo json_encode(['error' => 'Failed to update product']); + } } + /** + * Main entry point for the Products API. + */ public function index(): void { - switch ($_SERVER['REQUEST_METHOD']) { + $requestMethod = $_SERVER['REQUEST_METHOD']; + + switch ($requestMethod) { case 'GET': - $this->getProducts(); + if (isset($_GET['id'])) { + $productId = intval($_GET['id']); + $this->getProductById($productId); + } elseif (isset($_GET['categories'])) { + $this->getProductCategories(); + } else { + $this->getProducts(); + } break; case 'POST': - $this->addProduct(); + $this->createProduct(); break; case 'DELETE': - $this->deleteProduct(); + if (isset($_GET['id'])) { + $productId = intval($_GET['id']); + $this->deleteProduct($productId); + } else { + http_response_code(400); + echo json_encode(['error' => 'Product ID is required for deletion']); + } break; case 'PUT': - $this->updateProduct(); + if (isset($_GET['id'])) { + $productId = intval($_GET['id']); + $this->updateProduct($productId); + } else { + http_response_code(400); + echo json_encode(['error' => 'Product ID is required for update']); + } break; default: - http_response_code(400); - die(); + http_response_code(400); // Bad Request + echo json_encode(['error' => 'Invalid request method']); + break; } } -} \ No newline at end of file +} diff --git a/src/models/Product.php b/src/models/Product.php index 5c15b5f..ace774c 100644 --- a/src/models/Product.php +++ b/src/models/Product.php @@ -259,6 +259,7 @@ public function save(): bool return false; } } + public function getAverageRating(): float { @@ -287,6 +288,16 @@ public function getAverageRating(): float return 0; // No reviews, return 0 as the average rating } + public function delete(): bool + { + + $query = "DELETE FROM product WHERE product_id = :product_id"; + $data = ['product_id' => $this->product_id]; + $result = self::query($query, $data); + + return $result; + } + public function validate(): array { $errors = []; From ae0c2276571212b9b29180970ab3aff4fc0c386d Mon Sep 17 00:00:00 2001 From: creme332 <65414576+creme332@users.noreply.github.com> Date: Fri, 10 May 2024 13:33:07 +0400 Subject: [PATCH 02/10] use a cleaner way of mapping routes to functions --- src/controllers/api/Products.php | 149 +++++++++++++++++++------------ 1 file changed, 94 insertions(+), 55 deletions(-) diff --git a/src/controllers/api/Products.php b/src/controllers/api/Products.php index c6a37e3..4b9ae68 100644 --- a/src/controllers/api/Products.php +++ b/src/controllers/api/Products.php @@ -4,6 +4,7 @@ namespace Steamy\Controller\API; +use Steamy\Core\Utility; use Steamy\Model\Product; class Products @@ -11,7 +12,7 @@ class Products /** * Get the list of all products available in the store. */ - private function getProducts(): void + private function getAllProducts(): void { // Retrieve all products from the database $allProducts = Product::getAll(); @@ -29,8 +30,10 @@ private function getProducts(): void /** * Get the details of a specific product by its ID. */ - private function getProductById(int $productId): void + private function getProductById(): void { + $productId = (int)Utility::splitURL()[3]; + // Retrieve product details from the database $product = Product::getByID($productId); @@ -58,19 +61,38 @@ private function getProductCategories(): void echo json_encode($categories); } - /** - * Create a new product entry in the database. - */ + * Create a new product entry in the database. + */ private function createProduct(): void { // Retrieve POST data $postData = json_decode(file_get_contents("php://input"), true); + echo file_get_contents("php://input"); // ! always empty for some reason + + // TODO : Use json schema validation here // Check if required fields are present - $requiredFields = ['name', 'calories', 'img_url', 'img_alt_text', 'category', 'price', 'description', 'created_date']; + $requiredFields = [ + 'name', + 'calories', + 'img_url', + 'img_alt_text', + 'category', + 'price', + 'description' + ]; + + if (empty($postData)) { + http_response_code(400); + echo json_encode(['error' => "Missing fields: " . implode(', ', $requiredFields)]); + return; + } + + echo json_encode($postData); + foreach ($requiredFields as $field) { - if (!isset($postData[$field])) { + if (empty($postData[$field])) { // Required field is missing, return 400 Bad Request http_response_code(400); echo json_encode(['error' => "Missing required field: $field"]); @@ -86,15 +108,15 @@ private function createProduct(): void $postData['img_alt_text'], $postData['category'], (float)$postData['price'], - $postData['description'], - $postData['created_date'] + $postData['description'] ); // Save the new product to the database if ($newProduct->save()) { // Product created successfully, return 201 Created http_response_code(201); - echo json_encode(['message' => 'Product created successfully', 'product_id' => $newProduct->getProductID()]); + echo json_encode(['message' => 'Product created successfully', 'product_id' => $newProduct->getProductID()] + ); } else { // Failed to create product, return 500 Internal Server Error http_response_code(500); @@ -103,10 +125,12 @@ private function createProduct(): void } /** - * Delete a product with the specified ID. - */ - private function deleteProduct(int $productId): void + * Delete a product with the specified ID. + */ + private function deleteProduct(): void { + $productId = (int)Utility::splitURL()[3]; + // Retrieve the product by ID $product = Product::getByID($productId); @@ -129,12 +153,13 @@ private function deleteProduct(int $productId): void } } - /** - * Update the details of a product with the specified ID. - */ - private function updateProduct(int $productId): void + * Update the details of a product with the specified ID. + */ + private function updateProduct(): void { + $productId = (int)Utility::splitURL()[3]; + // Retrieve PUT request data $putData = json_decode(file_get_contents("php://input"), true); @@ -201,50 +226,64 @@ private function updateProduct(int $productId): void } } + private function getHandler($routes): ?string + { + foreach ($routes[$_SERVER['REQUEST_METHOD']] as $route => $handler) { + $pattern = str_replace('/', '\/', $route); // Convert to regex pattern + $pattern = preg_replace( + '/\{([a-zA-Z0-9_]+)\}/', + '(?P<$1>[^\/]+)', + $pattern + ); // Replace placeholders with regex capture groups + $pattern = '/^' . $pattern . '$/'; + + if (preg_match($pattern, '/' . Utility::getURL(), $matches)) { + return $handler; + } + } + return null; + } /** * Main entry point for the Products API. */ public function index(): void { - $requestMethod = $_SERVER['REQUEST_METHOD']; - - switch ($requestMethod) { - case 'GET': - if (isset($_GET['id'])) { - $productId = intval($_GET['id']); - $this->getProductById($productId); - } elseif (isset($_GET['categories'])) { - $this->getProductCategories(); - } else { - $this->getProducts(); - } - break; - case 'POST': - $this->createProduct(); - break; - case 'DELETE': - if (isset($_GET['id'])) { - $productId = intval($_GET['id']); - $this->deleteProduct($productId); - } else { - http_response_code(400); - echo json_encode(['error' => 'Product ID is required for deletion']); - } - break; - case 'PUT': - if (isset($_GET['id'])) { - $productId = intval($_GET['id']); - $this->updateProduct($productId); - } else { - http_response_code(400); - echo json_encode(['error' => 'Product ID is required for update']); - } - break; - default: - http_response_code(400); // Bad Request - echo json_encode(['error' => 'Invalid request method']); - break; + $routes = [ + 'GET' => [ + '/api/v1/products' => 'getAllProducts', + '/api/v1/products/categories' => 'getProductCategories', + '/api/v1/products/{id}' => 'getProductById', + ], + 'POST' => [ + '/api/v1/products' => 'createProduct', + ], + 'PUT' => [ + '/api/v1/products/{id}' => 'updateProduct', + ], + 'DELETE' => [ + '/api/v1/products/{id}' => 'deleteProduct', + ] + ]; + + // Handle the request + $handler = $this->getHandler($routes); + + if ($handler !== null) { + $functionName = $handler; + if (method_exists($this, $functionName)) { + call_user_func(array($this, $functionName)); + } else { + // Handle function not found + http_response_code(404); + echo "Function Not Found"; + die(); + } + } else { + // Handle route not found + http_response_code(404); + echo "Route Not Found"; + die(); } } } From 85208d8ec0baacdfb730ceba6d30a457be2417cc Mon Sep 17 00:00:00 2001 From: creme332 <65414576+creme332@users.noreply.github.com> Date: Sat, 11 May 2024 08:10:11 +0400 Subject: [PATCH 03/10] make delete return bool --- src/core/Model.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/core/Model.php b/src/core/Model.php index 361b366..600d069 100644 --- a/src/core/Model.php +++ b/src/core/Model.php @@ -152,12 +152,18 @@ protected function update(int|string $id, array $data, string $table_name, strin * @param mixed $id value of column name in WHERE clause. * @param string $table_name Name of table without backticks. Defaults to $this->table. * @param string $id_column_name primary key of table or name of column in WHERE clause. - * @return void + * @return bool Success or not */ - protected function delete(mixed $id, string $table_name, string $id_column_name = 'id'): void + protected function delete(mixed $id, string $table_name, string $id_column_name = 'id'): bool { $table_name = empty($table_name) ? $this->table : $table_name; $query = "DELETE FROM `$table_name` WHERE $id_column_name = :id"; - self::query($query, array('id' => $id)); + + $con = self::connect(); + $stm = $con->prepare($query); + $success = $stm->execute(['id' => $id]); + $con = null; + + return $success; } } From d5af3bb0b6d15f981827ec9c706690e8381909d3 Mon Sep 17 00:00:00 2001 From: creme332 <65414576+creme332@users.noreply.github.com> Date: Sat, 11 May 2024 08:14:06 +0400 Subject: [PATCH 04/10] fix delete not working --- src/models/Product.php | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/models/Product.php b/src/models/Product.php index 82c807a..d412fac 100644 --- a/src/models/Product.php +++ b/src/models/Product.php @@ -259,7 +259,7 @@ public function save(): bool return false; } } - + public function getAverageRating(): float { @@ -280,7 +280,7 @@ public function getAverageRating(): float WHERE op.product_id = r.product_id ) EOL; - + $params = ['product_id' => $this->product_id]; $result = $this->query($query, $params); @@ -294,14 +294,9 @@ public function getAverageRating(): float return 0; // No reviews, return 0 as the average rating } - public function delete(): bool + public function deleteProduct(): bool { - - $query = "DELETE FROM product WHERE product_id = :product_id"; - $data = ['product_id' => $this->product_id]; - $result = self::query($query, $data); - - return $result; + return $this->delete($this->product_id, $this->table, 'product_id'); } public function validate(): array From 60da2cf25faae9cf273b9de9c1e6b232a324830a Mon Sep 17 00:00:00 2001 From: creme332 <65414576+creme332@users.noreply.github.com> Date: Sat, 11 May 2024 08:14:28 +0400 Subject: [PATCH 05/10] fix bug in createProduct --- src/controllers/api/Products.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/controllers/api/Products.php b/src/controllers/api/Products.php index 4b9ae68..cf18c35 100644 --- a/src/controllers/api/Products.php +++ b/src/controllers/api/Products.php @@ -67,9 +67,7 @@ private function getProductCategories(): void private function createProduct(): void { // Retrieve POST data - $postData = json_decode(file_get_contents("php://input"), true); - echo file_get_contents("php://input"); // ! always empty for some reason - + $postData = $_POST; // TODO : Use json schema validation here // Check if required fields are present @@ -89,8 +87,6 @@ private function createProduct(): void return; } - echo json_encode($postData); - foreach ($requiredFields as $field) { if (empty($postData[$field])) { // Required field is missing, return 400 Bad Request @@ -143,7 +139,7 @@ private function deleteProduct(): void } // Attempt to delete the product - if ($product->delete()) { + if ($product->deleteProduct()) { // Product successfully deleted http_response_code(204); // No Content } else { From 80d638758b00d78f7795fda7394d45fbb52285b9 Mon Sep 17 00:00:00 2001 From: divyesh000 Date: Sat, 11 May 2024 09:01:49 +0400 Subject: [PATCH 06/10] use Model trait in Products class and update product attributes in a loop --- src/controllers/api/Products.php | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/src/controllers/api/Products.php b/src/controllers/api/Products.php index cf18c35..56fc3a2 100644 --- a/src/controllers/api/Products.php +++ b/src/controllers/api/Products.php @@ -6,9 +6,11 @@ use Steamy\Core\Utility; use Steamy\Model\Product; +use Steamy\Core\Model; class Products { + use Model; /** * Get the list of all products available in the store. */ @@ -179,26 +181,8 @@ private function updateProduct(): void } // Update product attributes - if (isset($putData['name'])) { - $product->setName($putData['name']); - } - if (isset($putData['calories'])) { - $product->setCalories(intval($putData['calories'])); - } - if (isset($putData['img_url'])) { - $product->setImgUrl($putData['img_url']); - } - if (isset($putData['img_alt_text'])) { - $product->setImgAltText($putData['img_alt_text']); - } - if (isset($putData['category'])) { - $product->setCategory($putData['category']); - } - if (isset($putData['price'])) { - $product->setPrice(floatval($putData['price'])); - } - if (isset($putData['description'])) { - $product->setDescription($putData['description']); + foreach ($putData as $key => $value) { + $product->{$key} = $value; } // Validate updated product attributes @@ -210,8 +194,11 @@ private function updateProduct(): void return; } - // Save updated product to the database - if ($product->save()) { + // Update product in the database + $rowsAffected = $product->update($productId, $putData, 'product'); + + // Check if update was successful + if ($rowsAffected > 0) { // Product updated successfully http_response_code(200); // OK echo json_encode(['message' => 'Product updated successfully']); From 4d52636f40c231c1b8a3518f3bed258310323e48 Mon Sep 17 00:00:00 2001 From: creme332 <65414576+creme332@users.noreply.github.com> Date: Thu, 16 May 2024 14:38:14 +0400 Subject: [PATCH 07/10] print exceptions by default --- src/controllers/API.php | 21 +++++++++++++++------ src/core/App.php | 4 +++- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/controllers/API.php b/src/controllers/API.php index 0ab4e29..d5ea393 100644 --- a/src/controllers/API.php +++ b/src/controllers/API.php @@ -4,6 +4,7 @@ namespace Steamy\Controller; +use Exception; use Steamy\Core\Controller; use Steamy\Core\Utility; @@ -26,7 +27,7 @@ public function __construct() } /** - * Checks if root relative url starts with /api/v1 + * Checks if root relative url starts with api/v1 * @return bool */ private function validateURLFormat(): bool @@ -37,17 +38,25 @@ private function validateURLFormat(): bool public function index(): void { if (!$this->validateURLFormat()) { - echo "Invalid API URL: " . $_GET["url"]; + http_response_code(400); die(); } // call appropriate controller to handle resource $controllerClassName = 'Steamy\\Controller\\API\\' . ucfirst($this->resource); + try { + if (class_exists($controllerClassName)) { + (new $controllerClassName())->index(); + } else { + http_response_code(404); + die(); + } + } catch (Exception $e) { + http_response_code(500); + + // Uncomment line below only when testing API + echo $e->getMessage(); - if (class_exists($controllerClassName)) { - (new $controllerClassName())->index(); - } else { - echo "Invalid API resource: " . $this->resource; die(); } } diff --git a/src/core/App.php b/src/core/App.php index 1f50d01..22523d5 100644 --- a/src/core/App.php +++ b/src/core/App.php @@ -18,7 +18,9 @@ class App */ public function exception_handler(Throwable $exception): void { -// echo "Uncaught exception: ", $exception->getMessage(), "\n"; + // Uncomment line below only during development + echo "Uncaught exception: ", $exception->getMessage(), "\n"; + (new Error())->handleUnknownError(); } From 715aa341145acfc298ffb95c62f2ec64f832909a Mon Sep 17 00:00:00 2001 From: creme332 <65414576+creme332@users.noreply.github.com> Date: Thu, 16 May 2024 14:40:33 +0400 Subject: [PATCH 08/10] rewrite `update` --- src/core/Model.php | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/core/Model.php b/src/core/Model.php index 600d069..1d1e2fc 100644 --- a/src/core/Model.php +++ b/src/core/Model.php @@ -116,35 +116,35 @@ protected function insert(array $data, string $table_name = ""): ?int return empty($lastInsertID) ? null : (int)$lastInsertID; } + /** - * Update a record in the table based on the provided ID. - * - * @param int|string $id The value of the primary key (ID) identifying the record to be updated. - * @param array $data An associative array representing the columns and their new values to be updated. - * @param string $table_name Name of table without backticks. Defaults to $this->table. - * @param string $id_column The name of the ID column. Default is 'id'. - * - * @return int Number of rows affected + * @param array $new_data Associative array for SET part of query. + * @param array $condition Associative array representing WHERE condition of query. + * @param string $table_name Defaults to $this->table. + * @return bool True on success. */ - protected function update(int|string $id, array $data, string $table_name, string $id_column = 'id'): int + protected function update(array $new_data, array $condition, string $table_name = ""): bool { $table_name = empty($table_name) ? $this->table : $table_name; - $keys = array_keys($data); $query = "UPDATE `$table_name` SET "; // add placeholders to query - foreach ($keys as $key) { + foreach (array_keys($new_data) as $key) { $query .= $key . " = :" . $key . ","; } + $query = trim($query, ", "); // remove extra comma at the end of query - // remove extra comma at the end of query - $query = trim($query, ", "); - - // add where condition - $query .= " WHERE $id_column = $id;"; + // add conditions + $query .= " WHERE "; + foreach (array_keys($condition) as $key) { + $query .= $key . " = :" . $key . ","; + } + $query = trim($query, ", "); // remove extra comma at the end of query $conn = self::connect(); - return $conn->exec($query); + $stm = $conn->prepare($query); + + return $stm->execute([...$new_data, ...$condition]); } /** From ae09ce01febdb3330473a42c108cbec65b7c38cd Mon Sep 17 00:00:00 2001 From: creme332 <65414576+creme332@users.noreply.github.com> Date: Thu, 16 May 2024 14:40:47 +0400 Subject: [PATCH 09/10] add updateProduct --- src/models/Product.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/models/Product.php b/src/models/Product.php index 0ec8ff3..1035c4b 100644 --- a/src/models/Product.php +++ b/src/models/Product.php @@ -416,4 +416,17 @@ public function getRatingDistribution(): array return $distribution; } + /** + * Updates product record in database but does not update the object itself. + * @param array $newProductData Associative array indexed by attribute name. + * The values are the new product data. + * @return bool Success or not + */ + public function updateProduct(array $newProductData): bool + { + // remove product_id (if present) from user data + unset($newProductData['product_id']); + + return $this->update($newProductData, ['product_id' => $this->product_id], $this->table); + } } \ No newline at end of file From 6ac06c7aedfb5ad990462ca06c6ed6a535e09ed1 Mon Sep 17 00:00:00 2001 From: creme332 <65414576+creme332@users.noreply.github.com> Date: Thu, 16 May 2024 14:41:22 +0400 Subject: [PATCH 10/10] fix bugs in updateProduct --- src/controllers/api/Products.php | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/src/controllers/api/Products.php b/src/controllers/api/Products.php index 56fc3a2..978005d 100644 --- a/src/controllers/api/Products.php +++ b/src/controllers/api/Products.php @@ -11,6 +11,7 @@ class Products { use Model; + /** * Get the list of all products available in the store. */ @@ -162,7 +163,7 @@ private function updateProduct(): void $putData = json_decode(file_get_contents("php://input"), true); // Check if PUT data is valid - if ($putData === null) { + if (empty($putData)) { // Invalid JSON data http_response_code(400); // Bad Request echo json_encode(['error' => 'Invalid JSON data']); @@ -180,25 +181,10 @@ private function updateProduct(): void return; } - // Update product attributes - foreach ($putData as $key => $value) { - $product->{$key} = $value; - } - - // Validate updated product attributes - $errors = $product->validate(); - if (!empty($errors)) { - // Validation errors - http_response_code(400); // Bad Request - echo json_encode(['error' => 'Validation failed', 'errors' => $errors]); - return; - } - // Update product in the database - $rowsAffected = $product->update($productId, $putData, 'product'); + $success = $product->updateProduct($putData); - // Check if update was successful - if ($rowsAffected > 0) { + if ($success) { // Product updated successfully http_response_code(200); // OK echo json_encode(['message' => 'Product updated successfully']);