Skip to content

Commit

Permalink
Merge pull request #236 from Divyeshhhh/comment-endpoint
Browse files Browse the repository at this point in the history
api controller for comments + tests
  • Loading branch information
creme332 authored Oct 9, 2024
2 parents ac65cc4 + 68e28a8 commit 58650f2
Show file tree
Hide file tree
Showing 7 changed files with 473 additions and 0 deletions.
12 changes: 12 additions & 0 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- [Product](#product)
- [Order](#order)
- [Review](#review)
- [Comment](#comment)
- [District](#district)
- [Query string parameters](#query-string-parameters)
- [References](#references)
Expand Down Expand Up @@ -80,6 +81,17 @@ A user can be a client or an administrator.
| `DELETE /api/v1/reviews/[id]` | Delete a review with the specified ID. | Yes |
| `GET /api/v1/reviews/stats/count-over-time` | Get the count of reviews for each month. | No | |


### Comment

| Endpoint | Description | Protected |
|--------------------------------------|--------------------------------------------------------|-----------|
| `GET /api/v1/comments` | Get the list of all comments. | No |
| `GET /api/v1/comments/[id]` | Get the details of a specific comments by its ID. | No |
| `POST /api/v1/comments` | Create a new comment for a product. | Yes |
| `PUT /api/v1/comments/[id]` | Update the details of a comment with the specified ID. | Yes |
| `DELETE /api/v1/comments/[id]` | Delete a comment with the specified ID. | Yes |

### District

| Endpoint | Description | Protected |
Expand Down
25 changes: 25 additions & 0 deletions resources/schemas/comments/create.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://example.com/comments/create.json",
"title": "Create Comment",
"properties": {
"text": {
"$ref": "https://example.com/common/comment.json#/properties/text"
},
"parent_comment_id": {
"$ref": "https://example.com/common/comment.json#/properties/parent_comment_id"
},
"user_id": {
"$ref": "https://example.com/common/comment.json#/properties/user_id"
},
"review_id": {
"$ref": "https://example.com/common/comment.json#/properties/review_id"
}
},
"required": [
"text",
"user_id",
"review_id"
],
"additionalProperties": false
}
20 changes: 20 additions & 0 deletions resources/schemas/comments/update.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://example.com/comments/update.json",
"title": "Update Comment",
"properties": {
"text": {
"$ref": "https://example.com/common/comment.json#/properties/text"
},
"parent_comment_id": {
"$ref": "https://example.com/common/comment.json#/properties/parent_comment_id"
},
"user_id": {
"$ref": "https://example.com/common/comment.json#/properties/user_id"
},
"review_id": {
"$ref": "https://example.com/common/comment.json#/properties/review_id"
}
},
"additionalProperties": false
}
37 changes: 37 additions & 0 deletions resources/schemas/common/comment.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://example.com/common/comment.json",
"title": "Comment",
"description": "A comment object",
"type": "object",
"properties": {
"comment_id": {
"type": "integer",
"description": "Unique identifier for the comment"
},
"text": {
"type": "string",
"description": "The text content of the comment",
"minLength": 1,
"maxLength": 2000
},
"created_date": {
"type": "string",
"format": "date-time",
"description": "The date and time when the comment was created"
},
"parent_comment_id": {
"type": ["integer", "null"],
"description": "The ID of the parent comment, if any"
},
"user_id": {
"type": "integer",
"description": "The ID of the user who made the comment"
},
"review_id": {
"type": "integer",
"description": "The ID of the review under which the comment is found"
}
},
"additionalProperties": false
}
171 changes: 171 additions & 0 deletions src/controllers/api/Comments.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
<?php

declare(strict_types=1);

namespace Steamy\Controller\API;

use Opis\JsonSchema\{Errors\ErrorFormatter};
use Steamy\Core\Utility;
use Steamy\Model\Comment;
use Steamy\Core\Model;

class Comments
{
use Model;

public static array $routes = [
'GET' => [
'/comments' => 'getAllComments',
'/comments/{id}' => 'getCommentById',
],
'POST' => [
'/comments' => 'createComment',
],
'PUT' => [
'/comments/{id}' => 'updateComment',
],
'DELETE' => [
'/comments/{id}' => 'deleteComment',
]
];

/**
* Get the list of all comments.
*/
public function getAllComments(): void
{
$allComments = Comment::getAll();

$result = [];
foreach ($allComments as $comment) {
$result[] = $comment->toArray();
}

echo json_encode($result);
}

/**
* Get the details of a specific comment by its ID.
*/
public function getCommentById(): void
{
$commentId = (int)Utility::splitURL()[3];

$comment = Comment::getByID($commentId);

if ($comment === null) {
http_response_code(404);
echo json_encode(['error' => 'Comment not found']);
return;
}

echo json_encode($comment->toArray());
}

/**
* Create a new comment.
*/
public function createComment(): void
{
$data = (object)json_decode(file_get_contents("php://input"), true);

// Validate input data against create.json schema
$result = Utility::validateAgainstSchema($data, "comments/create.json");

if (!($result->isValid())) {
$errors = (new ErrorFormatter())->format($result->error());
$response = [
'error' => $errors
];
http_response_code(400);
echo json_encode($response);
return;
}

// Create a new Comment object
$newComment = new Comment(
user_id: $data->user_id,
review_id: $data->review_id,
parent_comment_id: $data->parent_comment_id ?? null,
text: $data->text
);

// Save the new Comment to the database
if ($newComment->save()) {
// Comment created successfully, return 201 Created
http_response_code(201);
echo json_encode(['message' => 'Comment created successfully', 'comment_id' => $newComment->getCommentID()]
);
} else {
// Failed to create comment, return 500 Internal Server Error
http_response_code(500);
echo json_encode(['error' => 'Failed to create comment']);
}
}

/**
* Update the details of a comment with the specified ID.
*/
public function updateComment(): void
{
$commentId = (int)Utility::splitURL()[3];

$comment = Comment::getByID($commentId);

if ($comment === null) {
http_response_code(404);
echo json_encode(['error' => 'Comment not found']);
return;
}

$data = (object)json_decode(file_get_contents("php://input"), true);

// Validate input data against update.json schema
$result = Utility::validateAgainstSchema($data, "comments/update.json");

if (!($result->isValid())) {
$errors = (new ErrorFormatter())->format($result->error());
$response = [
'error' => $errors
];
http_response_code(400);
echo json_encode($response);
return;
}

// Update comment in the database
$success = $comment->updateComment((array)$data);

if ($success) {
http_response_code(200); // OK
echo json_encode(['message' => 'Comment updated successfully']);
} else {
http_response_code(500); // Internal Server Error
echo json_encode(['error' => 'Failed to update Comment']);
}
}

/**
* Delete a comment with the specified ID.
*/
public function deleteComment(): void
{
$commentId = (int)Utility::splitURL()[3];

$comment = Comment::getByID($commentId);

if ($comment === null) {
http_response_code(404);
echo json_encode(['error' => 'Comment not found']);
return;
}

if ($comment->deleteComment()) {
http_response_code(204); // No Content
} else {
http_response_code(500); // Internal Server Error
echo json_encode(['error' => 'Failed to delete comment']);
}

}
}
38 changes: 38 additions & 0 deletions src/models/Comment.php
Original file line number Diff line number Diff line change
Expand Up @@ -207,4 +207,42 @@ public function setCreatedDate(DateTime $created_date): void
{
$this->created_date = $created_date;
}

public function deleteComment(): bool
{
return $this->delete($this->comment_id, $this->table, 'comment_id');
}

/**
* Retrieve all comments.
*
* @return array An array of Comment objects.
*/
public static function getAll(): array
{
$query = "SELECT * FROM comment";
$result = Comment::query($query);

$comments = [];
foreach ($result as $row) {
$comments[] = new Comment(
user_id: $row->user_id,
review_id: $row->review_id,
comment_id: $row->comment_id,
parent_comment_id: $row->parent_comment_id,
text: $row->text,
created_date: Utility::stringToDate($row->created_date)
);
}

return $comments;
}

public function updateComment(array $newCommentData): bool
{
// remove comment_id (if present) from user data
unset($newCommentData['comment_id']);

return $this->update($newCommentData, ['comment_id' => $this->comment_id], $this->table);
}
}
Loading

0 comments on commit 58650f2

Please sign in to comment.